mirror of
				https://github.com/chylex/IntelliJ-Rainbow-Brackets.git
				synced 2025-11-04 01:40:20 +01:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			main
			...
			11754dea88
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						11754dea88
	
				 | 
					
					
						|||
| 
						
						
							
						
						3fc524f2d8
	
				 | 
					
					
						
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -2,5 +2,4 @@
 | 
				
			|||||||
!/.idea/runConfigurations
 | 
					!/.idea/runConfigurations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/.gradle/
 | 
					/.gradle/
 | 
				
			||||||
/.intellijPlatform/
 | 
					 | 
				
			||||||
/build/
 | 
					/build/
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					    <component name="CommitMessageInspectionProfile">
 | 
				
			||||||
 | 
					        <profile version="1.0">
 | 
				
			||||||
 | 
					            <inspection_tool class="GrazieCommit" enabled="true" level="TYPO" enabled_by_default="true"/>
 | 
				
			||||||
 | 
					        </profile>
 | 
				
			||||||
 | 
					    </component>
 | 
				
			||||||
 | 
					    <component name="VcsDirectoryMappings">
 | 
				
			||||||
 | 
					        <mapping directory="$PROJECT_DIR$" vcs="Git"/>
 | 
				
			||||||
 | 
					    </component>
 | 
				
			||||||
 | 
					    <component name="IssueNavigationConfiguration">
 | 
				
			||||||
 | 
					        <option name="links">
 | 
				
			||||||
 | 
					            <list>
 | 
				
			||||||
 | 
					                <IssueNavigationLink>
 | 
				
			||||||
 | 
					                    <option name="issueRegexp" value="#(\d+)"/>
 | 
				
			||||||
 | 
					                    <option name="linkRegexp" value="https://github.com//izhangzhihao/intellij-rainbow-brackets/issues/$1"/>
 | 
				
			||||||
 | 
					                </IssueNavigationLink>
 | 
				
			||||||
 | 
					            </list>
 | 
				
			||||||
 | 
					        </option>
 | 
				
			||||||
 | 
					    </component>
 | 
				
			||||||
 | 
					    <component name="VcsDirectoryMappings">
 | 
				
			||||||
 | 
					        <mapping directory="" vcs="Git"/>
 | 
				
			||||||
 | 
					    </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
@@ -4,9 +4,5 @@ This is a fork of the [🌈Rainbow Brackets](https://github.com/izhangzhihao/int
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Key Changes
 | 
					## Key Changes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Support for C# (Rider)
 | 
					- Support for CLion and Rider
 | 
				
			||||||
- Support for C++ (Rider, CLion, CLion Nova)
 | 
					 | 
				
			||||||
- Support for Settings Sync
 | 
					 | 
				
			||||||
- Improved highlighting performance
 | 
					 | 
				
			||||||
- Increased default setting for maximum line count from 1K to 100K
 | 
					 | 
				
			||||||
- Fixed service initialization warnings reported by 2024.2+
 | 
					- Fixed service initialization warnings reported by 2024.2+
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
val ideaVersion: String by project
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dependencies {
 | 
					 | 
				
			||||||
	intellijPlatform {
 | 
					 | 
				
			||||||
		@Suppress("DEPRECATION")
 | 
					 | 
				
			||||||
		intellijIdeaUltimate(ideaVersion)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										146
									
								
								build.gradle.kts
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								build.gradle.kts
									
									
									
									
									
								
							@@ -1,103 +1,131 @@
 | 
				
			|||||||
@file:Suppress("ConvertLambdaToReference")
 | 
					@file:Suppress("ConvertLambdaToReference")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
 | 
					import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 | 
				
			||||||
 | 
					import kotlin.io.path.Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
plugins {
 | 
					plugins {
 | 
				
			||||||
	kotlin("jvm")
 | 
						kotlin("jvm")
 | 
				
			||||||
	id("org.jetbrains.intellij.platform")
 | 
						id("org.jetbrains.intellij")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
group = "com.chylex.intellij.coloredbrackets"
 | 
					group = "com.chylex.intellij.coloredbrackets"
 | 
				
			||||||
version = "1.3.0"
 | 
					version = "1.0.0"
 | 
				
			||||||
 | 
					 | 
				
			||||||
val ideaVersion = "2023.3"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
allprojects {
 | 
					allprojects {
 | 
				
			||||||
	apply(plugin = "org.jetbrains.kotlin.jvm")
 | 
						apply(plugin = "org.jetbrains.kotlin.jvm")
 | 
				
			||||||
	apply(plugin = "org.jetbrains.intellij.platform")
 | 
						apply(plugin = "org.jetbrains.intellij")
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ext {
 | 
					 | 
				
			||||||
		set("ideaVersion", ideaVersion)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	repositories {
 | 
						repositories {
 | 
				
			||||||
		mavenCentral()
 | 
							mavenCentral()
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		intellijPlatform {
 | 
					 | 
				
			||||||
			defaultRepositories()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	intellijPlatform {
 | 
						intellij {
 | 
				
			||||||
		pluginConfiguration {
 | 
							version.set("2023.3")
 | 
				
			||||||
			ideaVersion {
 | 
							updateSinceUntilBuild.set(false)
 | 
				
			||||||
				sinceBuild.set("233")
 | 
					 | 
				
			||||||
				untilBuild.set(provider { null })
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	kotlin {
 | 
						kotlin {
 | 
				
			||||||
		jvmToolchain(17)
 | 
							jvmToolchain(17)
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		compilerOptions {
 | 
					 | 
				
			||||||
			freeCompilerArgs = listOf(
 | 
					 | 
				
			||||||
				"-X" + "jvm-default=all",
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						tasks.withType<KotlinCompile> {
 | 
				
			||||||
 | 
							kotlinOptions.freeCompilerArgs = listOf(
 | 
				
			||||||
 | 
								"-Xjvm-default=all"
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
subprojects {
 | 
					subprojects {
 | 
				
			||||||
	intellijPlatform {
 | 
						tasks.buildSearchableOptions {
 | 
				
			||||||
		buildSearchableOptions = false
 | 
							enabled = false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
idea {
 | 
					idea {
 | 
				
			||||||
	module {
 | 
						module {
 | 
				
			||||||
		excludeDirs.add(file("build"))
 | 
					 | 
				
			||||||
		excludeDirs.add(file("gradle"))
 | 
							excludeDirs.add(file("gradle"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					intellij {
 | 
				
			||||||
 | 
						type.set("IU")
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						plugins.set(
 | 
				
			||||||
 | 
							listOf(
 | 
				
			||||||
 | 
								// Built-in
 | 
				
			||||||
 | 
								"Groovy",
 | 
				
			||||||
 | 
								"JavaScript",
 | 
				
			||||||
 | 
								"com.intellij.css",
 | 
				
			||||||
 | 
								"com.intellij.database",
 | 
				
			||||||
 | 
								"com.intellij.java",
 | 
				
			||||||
 | 
								"org.intellij.plugins.markdown",
 | 
				
			||||||
 | 
								"org.jetbrains.kotlin",
 | 
				
			||||||
 | 
								"org.jetbrains.plugins.yaml",
 | 
				
			||||||
 | 
								// Downloaded
 | 
				
			||||||
 | 
								"Dart:233.11799.172",                              // https://plugins.jetbrains.com/plugin/6351-dart/versions/stable
 | 
				
			||||||
 | 
								"Pythonid:233.11799.300",                          // https://plugins.jetbrains.com/plugin/631-python/versions
 | 
				
			||||||
 | 
								"com.jetbrains.php:233.11799.300",                 // https://plugins.jetbrains.com/plugin/6610-php/versions
 | 
				
			||||||
 | 
								"com.jetbrains.sh:233.11799.165",                  // https://plugins.jetbrains.com/plugin/13122-shell-script/versions
 | 
				
			||||||
 | 
								"org.intellij.scala:2023.3.19",                    // https://plugins.jetbrains.com/plugin/1347-scala/versions
 | 
				
			||||||
 | 
								"org.jetbrains.plugins.go-template:233.11799.172", // https://plugins.jetbrains.com/plugin/10581-go-template/versions
 | 
				
			||||||
 | 
								"org.jetbrains.plugins.ruby:233.11799.300",        // https://plugins.jetbrains.com/plugin/1293-ruby/versions
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependencies {
 | 
					dependencies {
 | 
				
			||||||
	project(":api")
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	intellijPlatform {
 | 
					 | 
				
			||||||
		@Suppress("DEPRECATION")
 | 
					 | 
				
			||||||
		intellijIdeaUltimate(ideaVersion)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		bundledPlugin("JavaScript")
 | 
					 | 
				
			||||||
		bundledPlugin("com.intellij.css")
 | 
					 | 
				
			||||||
		bundledPlugin("com.intellij.database")
 | 
					 | 
				
			||||||
		bundledPlugin("com.intellij.java")
 | 
					 | 
				
			||||||
		bundledPlugin("org.intellij.groovy")
 | 
					 | 
				
			||||||
		bundledPlugin("org.intellij.plugins.markdown")
 | 
					 | 
				
			||||||
		bundledPlugin("org.jetbrains.kotlin")
 | 
					 | 
				
			||||||
		bundledPlugin("org.jetbrains.plugins.yaml")
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		plugin("Dart", "233.11799.172")                              // https://plugins.jetbrains.com/plugin/6351-dart/versions/stable
 | 
					 | 
				
			||||||
		plugin("PythonCore", "233.11799.300")                        // https://plugins.jetbrains.com/plugin/631-python/versions
 | 
					 | 
				
			||||||
		plugin("com.jetbrains.php", "233.11799.300")                 // https://plugins.jetbrains.com/plugin/6610-php/versions
 | 
					 | 
				
			||||||
		plugin("com.jetbrains.sh", "233.11799.165")                  // https://plugins.jetbrains.com/plugin/13122-shell-script/versions
 | 
					 | 
				
			||||||
		plugin("org.intellij.scala", "2023.3.19")                    // https://plugins.jetbrains.com/plugin/1347-scala/versions
 | 
					 | 
				
			||||||
		plugin("org.jetbrains.plugins.go-template", "233.11799.172") // https://plugins.jetbrains.com/plugin/10581-go-template/versions
 | 
					 | 
				
			||||||
		plugin("org.jetbrains.plugins.ruby", "233.11799.300")        // https://plugins.jetbrains.com/plugin/1293-ruby/versions
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		testFramework(TestFrameworkType.Plugin.Java)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		pluginComposedModule(implementation(project(":api")))
 | 
					 | 
				
			||||||
		pluginComposedModule(implementation(project(":clion")))
 | 
					 | 
				
			||||||
		pluginComposedModule(implementation(project(":rider")))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	testImplementation("junit:junit:4.13.2")
 | 
						testImplementation("junit:junit:4.13.2")
 | 
				
			||||||
	testImplementation("io.kotest:kotest-assertions-core:5.8.0") {
 | 
						testImplementation("io.kotest:kotest-assertions-core:5.8.0") {
 | 
				
			||||||
		exclude(group = "org.jetbrains.kotlin")
 | 
							exclude(group = "org.jetbrains.kotlin")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tasks.patchPluginXml {
 | 
				
			||||||
 | 
						sinceBuild.set("233")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tasks.test {
 | 
					tasks.test {
 | 
				
			||||||
	useJUnit()
 | 
						useJUnit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tasks.buildPlugin {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						val projectName = rootProject.name
 | 
				
			||||||
 | 
						val instrumentedJarName = "instrumented-$projectName-$version"
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for (ide in listOf("clion", "rider")) {
 | 
				
			||||||
 | 
							val task = project(":$ide").tasks.buildPlugin
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							dependsOn(task)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							from(task.map { it.outputs.files.map(::zipTree) }) {
 | 
				
			||||||
 | 
								include("$ide/lib/instrumented-$ide.jar")
 | 
				
			||||||
 | 
								into("lib")
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								eachFile {
 | 
				
			||||||
 | 
									val newName = name.replace("instrumented-", "${instrumentedJarName}-")
 | 
				
			||||||
 | 
									val newPath = relativePath.segments.dropLast(3).plus(newName)
 | 
				
			||||||
 | 
									relativePath = RelativePath(true, *newPath.toTypedArray())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								includeEmptyDirs = false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						doLast {
 | 
				
			||||||
 | 
							val expectedPaths = listOf(
 | 
				
			||||||
 | 
								Path(projectName, "lib", "instrumented-$projectName-$version-clion.jar"),
 | 
				
			||||||
 | 
								Path(projectName, "lib", "instrumented-$projectName-$version-rider.jar"),
 | 
				
			||||||
 | 
								Path(projectName, "lib", "instrumented-$projectName-$version.jar"),
 | 
				
			||||||
 | 
								Path(projectName, "lib", "searchableOptions-$version.jar"),
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							val jarFiles = zipTree(outputs.files.singleFile)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							for (expectedPath in expectedPaths) {
 | 
				
			||||||
 | 
								val found = jarFiles.find { it.toPath().endsWith(expectedPath) }
 | 
				
			||||||
 | 
								checkNotNull(found) { "Expected path not found: $expectedPath" }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
val ideaVersion: String by project
 | 
					intellij {
 | 
				
			||||||
 | 
						type.set("CL")
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						plugins.set(listOf(
 | 
				
			||||||
 | 
							// Built-in
 | 
				
			||||||
 | 
							"cidr-base-plugin"
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependencies {
 | 
					dependencies {
 | 
				
			||||||
	implementation(project(":api"))
 | 
						implementation(rootProject)
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	intellijPlatform {
 | 
					 | 
				
			||||||
		clion(ideaVersion)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		bundledPlugin("com.intellij.clion")
 | 
					 | 
				
			||||||
		// bundledPlugin("org.jetbrains.plugins.clion.radler") // Only in 2024.1 or newer. Worked around by only including the .xml file, and taking the implementation from Rider.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
<idea-plugin>
 | 
					 | 
				
			||||||
  <extensions defaultExtensionNs="com.chylex.coloredbrackets">
 | 
					 | 
				
			||||||
    <bracePairProvider language="C++"
 | 
					 | 
				
			||||||
                       implementationClass="com.chylex.intellij.coloredbrackets.provider.CppBracePairProvider" />
 | 
					 | 
				
			||||||
  </extensions>
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  <extensions defaultExtensionNs="com.intellij">
 | 
					 | 
				
			||||||
    <highlightVisitor implementation="com.chylex.intellij.coloredbrackets.visitor.CppRainbowVisitor" />
 | 
					 | 
				
			||||||
  </extensions>
 | 
					 | 
				
			||||||
</idea-plugin>
 | 
					 | 
				
			||||||
@@ -1,2 +1 @@
 | 
				
			|||||||
kotlin.stdlib.default.dependency=false
 | 
					kotlin.stdlib.default.dependency=false
 | 
				
			||||||
org.gradle.jvmargs=-Xmx1G
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
distributionBase=GRADLE_USER_HOME
 | 
					distributionBase=GRADLE_USER_HOME
 | 
				
			||||||
distributionPath=wrapper/dists
 | 
					distributionPath=wrapper/dists
 | 
				
			||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
 | 
					distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
 | 
				
			||||||
networkTimeout=10000
 | 
					networkTimeout=10000
 | 
				
			||||||
validateDistributionUrl=true
 | 
					validateDistributionUrl=true
 | 
				
			||||||
zipStoreBase=GRADLE_USER_HOME
 | 
					zipStoreBase=GRADLE_USER_HOME
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,7 @@
 | 
				
			|||||||
val ideaVersion: String by project
 | 
					intellij {
 | 
				
			||||||
 | 
						type.set("RD")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependencies {
 | 
					dependencies {
 | 
				
			||||||
	implementation(project(":api"))
 | 
						implementation(rootProject)
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	intellijPlatform {
 | 
					 | 
				
			||||||
		rider(ideaVersion) {
 | 
					 | 
				
			||||||
			useInstaller = false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
package com.chylex.intellij.coloredbrackets.provider
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.intellij.lang.BracePair
 | 
					 | 
				
			||||||
import com.jetbrains.rider.cpp.fileType.lexer.CppTokenTypes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CppBracePairProvider : BracePairProvider {
 | 
					 | 
				
			||||||
	override fun pairs(): List<BracePair> = listOf(
 | 
					 | 
				
			||||||
		BracePair(CppTokenTypes.LPAR, CppTokenTypes.RPAR, false),
 | 
					 | 
				
			||||||
		BracePair(CppTokenTypes.LBRACE, CppTokenTypes.RBRACE, false),
 | 
					 | 
				
			||||||
		BracePair(CppTokenTypes.LBRACKET, CppTokenTypes.RBRACKET, false),
 | 
					 | 
				
			||||||
		BracePair(CppTokenTypes.LT, CppTokenTypes.GT, false),
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -2,25 +2,130 @@ package com.chylex.intellij.coloredbrackets.visitor
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
 | 
					import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
 | 
				
			||||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
 | 
					import com.intellij.codeInsight.daemon.impl.HighlightVisitor
 | 
				
			||||||
 | 
					import com.intellij.lang.BracePair
 | 
				
			||||||
import com.intellij.psi.PsiElement
 | 
					import com.intellij.psi.PsiElement
 | 
				
			||||||
import com.intellij.psi.PsiFile
 | 
					import com.intellij.psi.PsiFile
 | 
				
			||||||
 | 
					import com.intellij.psi.impl.source.tree.LeafPsiElement
 | 
				
			||||||
import com.intellij.psi.tree.IElementType
 | 
					import com.intellij.psi.tree.IElementType
 | 
				
			||||||
import com.jetbrains.rider.languages.fileTypes.csharp.kotoparser.lexer.CSharpTokenType
 | 
					import com.jetbrains.rider.languages.fileTypes.csharp.kotoparser.lexer.CSharpTokenType
 | 
				
			||||||
import com.jetbrains.rider.languages.fileTypes.csharp.psi.CSharpDummyNode
 | 
					import com.jetbrains.rider.languages.fileTypes.csharp.psi.CSharpDummyNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CSharpRainbowVisitor : ReSharperRainbowVisitor("C#") {
 | 
					class CSharpRainbowVisitor : RainbowHighlightVisitor() {
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun suitableForFile(file: PsiFile): Boolean {
 | 
						override fun suitableForFile(file: PsiFile)
 | 
				
			||||||
		return super.suitableForFile(file) && RainbowSettings.instance.isEnableRainbowAngleBrackets
 | 
							: Boolean = super.suitableForFile(file) &&
 | 
				
			||||||
	}
 | 
							RainbowSettings.instance.isEnableRainbowAngleBrackets &&
 | 
				
			||||||
	
 | 
							(file.language.id == "C#" ||
 | 
				
			||||||
	override fun isAllowedElementType(type: IElementType): Boolean {
 | 
								file.viewProvider.allFiles.any { it.language.id == "C#" }
 | 
				
			||||||
		return type == CSharpTokenType.LPARENTH || type == CSharpTokenType.RPARENTH
 | 
								)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	override fun PsiElement.isDummyNode(): Boolean {
 | 
					 | 
				
			||||||
		return this is CSharpDummyNode
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun clone(): HighlightVisitor = CSharpRainbowVisitor()
 | 
						override fun clone(): HighlightVisitor = CSharpRainbowVisitor()
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						override fun visit(element: PsiElement) {
 | 
				
			||||||
 | 
							val type = (element as? LeafPsiElement)?.elementType ?: return
 | 
				
			||||||
 | 
							val pair = map[type]
 | 
				
			||||||
 | 
							if (pair != null) {
 | 
				
			||||||
 | 
								val level = element.getBracketLevel(pair, type)
 | 
				
			||||||
 | 
								if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
 | 
				
			||||||
 | 
									if (level >= 1) {
 | 
				
			||||||
 | 
										rainbowPairs(element, pair, level)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									if (level >= 0) {
 | 
				
			||||||
 | 
										rainbowPairs(element, pair, level)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
 | 
				
			||||||
 | 
							val startElement = element.takeIf { it.elementType == pair.leftBraceType }
 | 
				
			||||||
 | 
							val endElement = element.takeIf { it.elementType == pair.rightBraceType }
 | 
				
			||||||
 | 
							element.setHighlightInfo(element.parent, level, startElement, endElement)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						companion object {
 | 
				
			||||||
 | 
							val map = mapOf(
 | 
				
			||||||
 | 
								CSharpTokenType.LPARENTH to BracePair(CSharpTokenType.LPARENTH, CSharpTokenType.RPARENTH, true),
 | 
				
			||||||
 | 
								CSharpTokenType.RPARENTH to BracePair(CSharpTokenType.LPARENTH, CSharpTokenType.RPARENTH, true),
 | 
				
			||||||
 | 
								//LT to BracePair(LT, GT, true),
 | 
				
			||||||
 | 
								//GT to BracePair(LT, GT, true),
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							private fun LeafPsiElement.getBracketLevel(pair: BracePair, type: IElementType): Int = iterateBracketParents(this, pair, -1, type)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							private tailrec fun iterateBracketParents(element: PsiElement?, pair: BracePair, count: Int, type: IElementType): Int {
 | 
				
			||||||
 | 
								if (element == null || element is PsiFile) {
 | 
				
			||||||
 | 
									return count
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								var nextCount = count
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if (element is LeafPsiElement && type == pair.leftBraceType && element.elementType == pair.rightBraceType) {
 | 
				
			||||||
 | 
									nextCount--
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if (element is LeafPsiElement && type == pair.rightBraceType && element.elementType == pair.leftBraceType) {
 | 
				
			||||||
 | 
									nextCount--
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if (element is LeafPsiElement && element.elementType == type) {
 | 
				
			||||||
 | 
									nextCount++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								return if (type == pair.leftBraceType) {
 | 
				
			||||||
 | 
									val prev = element.prevSibling
 | 
				
			||||||
 | 
									if (prev == null) {
 | 
				
			||||||
 | 
										iterateBracketParents(element.parent.prevSibling.iterForPreDummyNode()?.lastChild, pair, nextCount, type)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
 | 
										iterateBracketParents(prev, pair, nextCount, type)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									val next = element.nextSibling
 | 
				
			||||||
 | 
									if (next == null) {
 | 
				
			||||||
 | 
										iterateBracketParents(element.parent.nextSibling.iterForNextDummyNode()?.firstChild, pair, nextCount, type)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
 | 
										iterateBracketParents(next, pair, nextCount, type)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							private tailrec fun PsiElement?.iterForNextDummyNode(): PsiElement? {
 | 
				
			||||||
 | 
								return if (this == null) {
 | 
				
			||||||
 | 
									null
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (this is CSharpDummyNode) {
 | 
				
			||||||
 | 
									this
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									if (this.nextSibling == null) {
 | 
				
			||||||
 | 
										null
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
 | 
										this.nextSibling.iterForNextDummyNode()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							private tailrec fun PsiElement?.iterForPreDummyNode(): PsiElement? {
 | 
				
			||||||
 | 
								return if (this == null) {
 | 
				
			||||||
 | 
									null
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (this is CSharpDummyNode) {
 | 
				
			||||||
 | 
									this
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									if (this.prevSibling == null) {
 | 
				
			||||||
 | 
										null
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
 | 
										this.prevSibling.iterForPreDummyNode()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +0,0 @@
 | 
				
			|||||||
package com.chylex.intellij.coloredbrackets.visitor
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
 | 
					 | 
				
			||||||
import com.intellij.psi.PsiElement
 | 
					 | 
				
			||||||
import com.intellij.psi.tree.IElementType
 | 
					 | 
				
			||||||
import com.jetbrains.rider.cpp.fileType.lexer.CppTokenTypes
 | 
					 | 
				
			||||||
import com.jetbrains.rider.cpp.fileType.psi.CppDummyNode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CppRainbowVisitor : ReSharperRainbowVisitor("C++") {
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	override fun clone(): HighlightVisitor = CppRainbowVisitor()
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	override fun isAllowedElementType(type: IElementType): Boolean {
 | 
					 | 
				
			||||||
		return type == CppTokenTypes.LPAR || type == CppTokenTypes.RPAR
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	override fun PsiElement.isDummyNode(): Boolean {
 | 
					 | 
				
			||||||
		return this is CppDummyNode
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,120 +0,0 @@
 | 
				
			|||||||
package com.chylex.intellij.coloredbrackets.visitor
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.BracePairs.bracePairs
 | 
					 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
 | 
					 | 
				
			||||||
import com.intellij.lang.BracePair
 | 
					 | 
				
			||||||
import com.intellij.psi.PsiElement
 | 
					 | 
				
			||||||
import com.intellij.psi.PsiFile
 | 
					 | 
				
			||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
 | 
					 | 
				
			||||||
import com.intellij.psi.tree.IElementType
 | 
					 | 
				
			||||||
import com.intellij.psi.util.elementType
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class ReSharperRainbowVisitor(private val languageId: String) : RainbowHighlightVisitor() {
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	override fun suitableForFile(file: PsiFile): Boolean {
 | 
					 | 
				
			||||||
		return super.suitableForFile(file) && (file.language.id == languageId || file.viewProvider.allFiles.any { it.language.id == languageId })
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	protected abstract fun isAllowedElementType(type: IElementType): Boolean
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	final override fun visit(element: PsiElement) {
 | 
					 | 
				
			||||||
		val type = (element as? LeafPsiElement)?.elementType?.takeIf(::isAllowedElementType) ?: return
 | 
					 | 
				
			||||||
		val pair = type.language.bracePairs?.getValue(type.toString())?.singleOrNull() ?: return
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		val settings = RainbowSettings.instance
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (settings.isDoNOTRainbowifyBracketsWithoutContent) {
 | 
					 | 
				
			||||||
			if (pair.leftBraceType == type && element.nextSibling?.elementType == pair.rightBraceType) {
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			if (pair.rightBraceType == type && element.prevSibling?.elementType == pair.leftBraceType) {
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		val level = element.getBracketLevel(pair, type)
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (settings.isDoNOTRainbowifyTheFirstLevel) {
 | 
					 | 
				
			||||||
			if (level >= 1) {
 | 
					 | 
				
			||||||
				rainbowPairs(element, pair, level)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			if (level >= 0) {
 | 
					 | 
				
			||||||
				rainbowPairs(element, pair, level)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
 | 
					 | 
				
			||||||
		val startElement = element.takeIf { it.elementType == pair.leftBraceType }
 | 
					 | 
				
			||||||
		val endElement = element.takeIf { it.elementType == pair.rightBraceType }
 | 
					 | 
				
			||||||
		element.setHighlightInfo(element.parent, level, startElement, endElement)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private fun LeafPsiElement.getBracketLevel(pair: BracePair, type: IElementType): Int {
 | 
					 | 
				
			||||||
		return iterateBracketParents(this, pair, -1, type)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private tailrec fun iterateBracketParents(element: PsiElement?, pair: BracePair, count: Int, type: IElementType): Int {
 | 
					 | 
				
			||||||
		if (element == null || element is PsiFile) {
 | 
					 | 
				
			||||||
			return count
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		var nextCount = count
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (element is LeafPsiElement) {
 | 
					 | 
				
			||||||
			if (type == pair.leftBraceType && element.elementType == pair.rightBraceType) {
 | 
					 | 
				
			||||||
				nextCount--
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			if (type == pair.rightBraceType && element.elementType == pair.leftBraceType) {
 | 
					 | 
				
			||||||
				nextCount--
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			if (type == element.elementType) {
 | 
					 | 
				
			||||||
				nextCount++
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		return if (type == pair.leftBraceType) {
 | 
					 | 
				
			||||||
			val prev = element.prevSibling
 | 
					 | 
				
			||||||
			if (prev == null) {
 | 
					 | 
				
			||||||
				iterateBracketParents(element.parent.prevSibling.iterForPreDummyNode()?.lastChild, pair, nextCount, type)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else {
 | 
					 | 
				
			||||||
				iterateBracketParents(prev, pair, nextCount, type)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			val next = element.nextSibling
 | 
					 | 
				
			||||||
			if (next == null) {
 | 
					 | 
				
			||||||
				iterateBracketParents(element.parent.nextSibling.iterForNextDummyNode()?.firstChild, pair, nextCount, type)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else {
 | 
					 | 
				
			||||||
				iterateBracketParents(next, pair, nextCount, type)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	protected abstract fun PsiElement.isDummyNode(): Boolean
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private tailrec fun PsiElement?.iterForNextDummyNode(): PsiElement? {
 | 
					 | 
				
			||||||
		return when {
 | 
					 | 
				
			||||||
			this == null             -> null
 | 
					 | 
				
			||||||
			this.isDummyNode()       -> this
 | 
					 | 
				
			||||||
			this.nextSibling == null -> null
 | 
					 | 
				
			||||||
			else                     -> this.nextSibling.iterForNextDummyNode()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private tailrec fun PsiElement?.iterForPreDummyNode(): PsiElement? {
 | 
					 | 
				
			||||||
		return when {
 | 
					 | 
				
			||||||
			this == null             -> null
 | 
					 | 
				
			||||||
			this.isDummyNode()       -> this
 | 
					 | 
				
			||||||
			this.prevSibling == null -> null
 | 
					 | 
				
			||||||
			else                     -> this.prevSibling.iterForPreDummyNode()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
<idea-plugin>
 | 
					 | 
				
			||||||
  <extensions defaultExtensionNs="com.chylex.coloredbrackets">
 | 
					 | 
				
			||||||
    <bracePairProvider language="C++"
 | 
					 | 
				
			||||||
                       implementationClass="com.chylex.intellij.coloredbrackets.provider.CppBracePairProvider" />
 | 
					 | 
				
			||||||
  </extensions>
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  <extensions defaultExtensionNs="com.intellij">
 | 
					 | 
				
			||||||
    <highlightVisitor implementation="com.chylex.intellij.coloredbrackets.visitor.CppRainbowVisitor" />
 | 
					 | 
				
			||||||
  </extensions>
 | 
					 | 
				
			||||||
</idea-plugin>
 | 
					 | 
				
			||||||
@@ -3,10 +3,9 @@ rootProject.name = "ColoredBrackets"
 | 
				
			|||||||
pluginManagement {
 | 
					pluginManagement {
 | 
				
			||||||
	plugins {
 | 
						plugins {
 | 
				
			||||||
		kotlin("jvm") version "1.9.21"
 | 
							kotlin("jvm") version "1.9.21"
 | 
				
			||||||
		id("org.jetbrains.intellij.platform") version "2.9.0"
 | 
							id("org.jetbrains.intellij") version "1.17.4"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include("api")
 | 
					 | 
				
			||||||
include("clion")
 | 
					include("clion")
 | 
				
			||||||
include("rider")
 | 
					include("rider")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ object BracePairs {
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	private val providers = LanguageExtension<BracePairProvider>("com.chylex.coloredbrackets.bracePairProvider")
 | 
						private val providers = LanguageExtension<BracePairProvider>("com.chylex.coloredbrackets.bracePairProvider")
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	val bracePairs = lazy {
 | 
						private val bracePairs = lazy {
 | 
				
			||||||
		Language.getRegisteredLanguages()
 | 
							Language.getRegisteredLanguages()
 | 
				
			||||||
			.map { language ->
 | 
								.map { language ->
 | 
				
			||||||
				if (language is CompositeLanguage) {
 | 
									if (language is CompositeLanguage) {
 | 
				
			||||||
@@ -69,18 +69,20 @@ object BracePairs {
 | 
				
			|||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				language.id to braceMap
 | 
									language.displayName to braceMap
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			.toMap()
 | 
								.toMap()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private fun getBraceTypeSetOf(language: Language): Set<IElementType> = language.bracePairs?.values?.flatten()?.map { listOf(it.leftBraceType, it.rightBraceType) }?.flatten()?.toSet() ?: emptySet()
 | 
						fun getBracePairs(language: Language): MutableMap<String, MutableList<BracePair>>? = bracePairs.value[language.displayName]
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private fun getBraceTypeSetOf(language: Language): Set<IElementType> = getBracePairs(language)?.values?.flatten()?.map { listOf(it.leftBraceType, it.rightBraceType) }?.flatten()?.toSet() ?: emptySet()
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	val braceTypeSet: (Language) -> Set<IElementType> = { language: Language -> getBraceTypeSetOf(language) }.memoize()
 | 
						val braceTypeSet: (Language) -> Set<IElementType> = { language: Language -> getBraceTypeSetOf(language) }.memoize()
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	inline val Language.bracePairs: MutableMap<String, MutableList<BracePair>>?
 | 
					 | 
				
			||||||
		get() = BracePairs.bracePairs.value[this.id]
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	inline val Language.braceTypeSet: Set<IElementType>
 | 
					 | 
				
			||||||
		get() = BracePairs.braceTypeSet(this)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline val Language.bracePairs: MutableMap<String, MutableList<BracePair>>?
 | 
				
			||||||
 | 
						get() = BracePairs.getBracePairs(this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline val Language.braceTypeSet: Set<IElementType>
 | 
				
			||||||
 | 
						get() = BracePairs.braceTypeSet(this)
 | 
				
			||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
package com.chylex.intellij.coloredbrackets
 | 
					package com.chylex.intellij.coloredbrackets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
 | 
					import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.util.create
 | 
					 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.util.memoize
 | 
					import com.chylex.intellij.coloredbrackets.util.memoize
 | 
				
			||||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
 | 
					import com.intellij.codeInsight.daemon.impl.HighlightInfo
 | 
				
			||||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType
 | 
					import com.intellij.codeInsight.daemon.impl.HighlightInfoType
 | 
				
			||||||
@@ -138,7 +137,7 @@ object RainbowHighlighter {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private fun genByOption(option: String, rainbowName: String, level: Int) =
 | 
						private fun genByOption(option: String, rainbowName: String, level: Int) =
 | 
				
			||||||
		create(
 | 
							com.chylex.intellij.coloredbrackets.util.create(
 | 
				
			||||||
			"$rainbowName-$level",
 | 
								"$rainbowName-$level",
 | 
				
			||||||
			TextAttributes(randomColor(option), null, null, null, 0)
 | 
								TextAttributes(randomColor(option), null, null, null, 0)
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
@@ -9,27 +9,21 @@ import com.intellij.icons.AllIcons
 | 
				
			|||||||
import com.intellij.ide.actions.ShowSettingsUtilImpl
 | 
					import com.intellij.ide.actions.ShowSettingsUtilImpl
 | 
				
			||||||
import com.intellij.openapi.fileEditor.FileEditor
 | 
					import com.intellij.openapi.fileEditor.FileEditor
 | 
				
			||||||
import com.intellij.openapi.project.Project
 | 
					import com.intellij.openapi.project.Project
 | 
				
			||||||
 | 
					import com.intellij.openapi.util.Key
 | 
				
			||||||
import com.intellij.openapi.util.Ref
 | 
					import com.intellij.openapi.util.Ref
 | 
				
			||||||
import com.intellij.openapi.vfs.VirtualFile
 | 
					import com.intellij.openapi.vfs.VirtualFile
 | 
				
			||||||
import com.intellij.ui.EditorNotificationPanel
 | 
					import com.intellij.ui.EditorNotificationPanel
 | 
				
			||||||
import com.intellij.ui.EditorNotificationProvider
 | 
					 | 
				
			||||||
import com.intellij.ui.EditorNotifications
 | 
					import com.intellij.ui.EditorNotifications
 | 
				
			||||||
import com.intellij.ui.HyperlinkLabel
 | 
					import com.intellij.ui.HyperlinkLabel
 | 
				
			||||||
import java.util.function.Function
 | 
					 | 
				
			||||||
import javax.swing.JComponent
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RainbowifyBanner : EditorNotificationProvider {
 | 
					class RainbowifyBanner : EditorNotifications.Provider<EditorNotificationPanel>() {
 | 
				
			||||||
	override fun collectNotificationData(project: Project, file: VirtualFile): Function<in FileEditor, out JComponent?> {
 | 
						override fun getKey(): Key<EditorNotificationPanel> = KEY
 | 
				
			||||||
		return Function { createNotificationPanel(project, file) }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private fun createNotificationPanel(project: Project, file: VirtualFile): EditorNotificationPanel? {
 | 
						override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor, project: Project): EditorNotificationPanel? {
 | 
				
			||||||
		val settings = RainbowSettings.instance
 | 
							val settings = RainbowSettings.instance
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		if (!settings.isRainbowEnabled) {
 | 
							if (!settings.isRainbowEnabled) {
 | 
				
			||||||
			if (settings.suppressDisabledCheck) {
 | 
								if (settings.suppressDisabledCheck) return null
 | 
				
			||||||
				return null
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return EditorNotificationPanel().apply {
 | 
								return EditorNotificationPanel().apply {
 | 
				
			||||||
				text("Colored Brackets is now disabled")
 | 
									text("Colored Brackets is now disabled")
 | 
				
			||||||
				icon(AllIcons.General.GearPlain)
 | 
									icon(AllIcons.General.GearPlain)
 | 
				
			||||||
@@ -47,9 +41,7 @@ class RainbowifyBanner : EditorNotificationProvider {
 | 
				
			|||||||
		
 | 
							
 | 
				
			||||||
		val psiFile = file.toPsiFile(project)
 | 
							val psiFile = file.toPsiFile(project)
 | 
				
			||||||
		if (psiFile != null && !checkForBigFile(psiFile)) {
 | 
							if (psiFile != null && !checkForBigFile(psiFile)) {
 | 
				
			||||||
			if (settings.suppressBigFileCheck) {
 | 
								if (settings.suppressBigFileCheck) return null
 | 
				
			||||||
				return null
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return EditorNotificationPanel().apply {
 | 
								return EditorNotificationPanel().apply {
 | 
				
			||||||
				text("Rainbowify is disabled for files > " + settings.bigFilesLinesThreshold + " lines")
 | 
									text("Rainbowify is disabled for files > " + settings.bigFilesLinesThreshold + " lines")
 | 
				
			||||||
				icon(AllIcons.General.InspectionsEye)
 | 
									icon(AllIcons.General.InspectionsEye)
 | 
				
			||||||
@@ -69,9 +61,7 @@ class RainbowifyBanner : EditorNotificationProvider {
 | 
				
			|||||||
			settings.languageBlacklist.contains(file.fileType.name) ||
 | 
								settings.languageBlacklist.contains(file.fileType.name) ||
 | 
				
			||||||
			settings.languageBlacklist.contains(memoizedFileExtension(file.name))
 | 
								settings.languageBlacklist.contains(memoizedFileExtension(file.name))
 | 
				
			||||||
		) {
 | 
							) {
 | 
				
			||||||
			if (settings.suppressBlackListCheck) {
 | 
								if (settings.suppressBlackListCheck) return null
 | 
				
			||||||
				return null
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return EditorNotificationPanel().apply {
 | 
								return EditorNotificationPanel().apply {
 | 
				
			||||||
				text("Rainbowify is disabled because the language/file extension is in the black list")
 | 
									text("Rainbowify is disabled because the language/file extension is in the black list")
 | 
				
			||||||
				icon(AllIcons.General.InspectionsEye)
 | 
									icon(AllIcons.General.InspectionsEye)
 | 
				
			||||||
@@ -91,10 +81,14 @@ class RainbowifyBanner : EditorNotificationProvider {
 | 
				
			|||||||
		return null
 | 
							return null
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
 | 
						companion object {
 | 
				
			||||||
 | 
							private val KEY = Key.create<EditorNotificationPanel>("RainbowifyBanner")
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
 | 
				
			||||||
			val label: Ref<HyperlinkLabel> = Ref.create()
 | 
								val label: Ref<HyperlinkLabel> = Ref.create()
 | 
				
			||||||
			label.set(createActionLabel(labelText) {
 | 
								label.set(createActionLabel(labelText) {
 | 
				
			||||||
				callback(label.get())
 | 
									callback(label.get())
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ package com.chylex.intellij.coloredbrackets
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.color.Luminosity
 | 
					import com.chylex.intellij.coloredbrackets.color.Luminosity
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.color.fromString
 | 
					import com.chylex.intellij.coloredbrackets.color.fromString
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.color.randomColor
 | 
					 | 
				
			||||||
import com.fasterxml.jackson.databind.ObjectMapper
 | 
					import com.fasterxml.jackson.databind.ObjectMapper
 | 
				
			||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 | 
					import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 | 
				
			||||||
import com.fasterxml.jackson.module.kotlin.readValue
 | 
					import com.fasterxml.jackson.module.kotlin.readValue
 | 
				
			||||||
@@ -12,7 +11,7 @@ val mapper: ObjectMapper by lazy { jacksonObjectMapper() }
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
fun randomColor(options: String): Color {
 | 
					fun randomColor(options: String): Color {
 | 
				
			||||||
	val ops: Map<String, String> = mapper.readValue(options)
 | 
						val ops: Map<String, String> = mapper.readValue(options)
 | 
				
			||||||
	return randomColor(
 | 
						return com.chylex.intellij.coloredbrackets.color.randomColor(
 | 
				
			||||||
		fromString(ops.getOrDefault("hue", "random")),
 | 
							fromString(ops.getOrDefault("hue", "random")),
 | 
				
			||||||
		Luminosity.valueOf(ops.getOrDefault("luminosity", "random"))
 | 
							Luminosity.valueOf(ops.getOrDefault("luminosity", "random"))
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
@@ -16,7 +16,7 @@ class KotlinLambdaExpressionArrowAnnotator : Annotator {
 | 
				
			|||||||
		if ((element as? LeafPsiElement)?.elementType == KtTokens.ARROW) {
 | 
							if ((element as? LeafPsiElement)?.elementType == KtTokens.ARROW) {
 | 
				
			||||||
			RainbowInfo.RAINBOW_INFO_KEY[element.parent]?.color?.let {
 | 
								RainbowInfo.RAINBOW_INFO_KEY[element.parent]?.color?.let {
 | 
				
			||||||
				holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
 | 
									holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
 | 
				
			||||||
					.range(element as PsiElement) // Cast necessary due to overload conflict in Kotlin 2 compiler.
 | 
										.range(element)
 | 
				
			||||||
					.textAttributes(
 | 
										.textAttributes(
 | 
				
			||||||
						com.chylex.intellij.coloredbrackets.util.create(
 | 
											com.chylex.intellij.coloredbrackets.util.create(
 | 
				
			||||||
							"rainbow-kotlin-arrow",
 | 
												"rainbow-kotlin-arrow",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@ import com.chylex.intellij.coloredbrackets.util.findNextSibling
 | 
				
			|||||||
import com.chylex.intellij.coloredbrackets.util.findPrevSibling
 | 
					import com.chylex.intellij.coloredbrackets.util.findPrevSibling
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.util.lineNumber
 | 
					import com.chylex.intellij.coloredbrackets.util.lineNumber
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.util.startOffset
 | 
					import com.chylex.intellij.coloredbrackets.util.startOffset
 | 
				
			||||||
import com.intellij.openapi.application.ReadAction
 | 
					 | 
				
			||||||
import com.intellij.openapi.editor.Document
 | 
					import com.intellij.openapi.editor.Document
 | 
				
			||||||
import com.intellij.openapi.editor.Editor
 | 
					import com.intellij.openapi.editor.Editor
 | 
				
			||||||
import com.intellij.openapi.editor.SoftWrap
 | 
					import com.intellij.openapi.editor.SoftWrap
 | 
				
			||||||
@@ -166,28 +165,24 @@ class RainbowIndentGuideRenderer : CustomHighlighterRenderer {
 | 
				
			|||||||
			val virtualFile = editor.virtualFile?.takeIf { it.isValid } ?: return null
 | 
								val virtualFile = editor.virtualFile?.takeIf { it.isValid } ?: return null
 | 
				
			||||||
			val document = editor.document
 | 
								val document = editor.document
 | 
				
			||||||
			val project = editor.project ?: return null
 | 
								val project = editor.project ?: return null
 | 
				
			||||||
			
 | 
								val psiFile = PsiManager.getInstance(project).findFile(virtualFile) ?: return null
 | 
				
			||||||
			return ReadAction.compute<RainbowInfo, Throwable> {
 | 
					 | 
				
			||||||
				val psiFile = PsiManager.getInstance(project).findFile(virtualFile) ?: return@compute null
 | 
					 | 
				
			||||||
			var element = try {
 | 
								var element = try {
 | 
				
			||||||
					psiFile.findElementAt(highlighter.endOffset)?.parent ?: return@compute null
 | 
									psiFile.findElementAt(highlighter.endOffset)?.parent ?: return null
 | 
				
			||||||
				} catch (_: Throwable) {
 | 
								} catch (e: Throwable) {
 | 
				
			||||||
					return@compute null
 | 
									return null
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			var rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element]
 | 
								var rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element]
 | 
				
			||||||
			if (rainbowInfo == null && psiFile is XmlFile && element !is XmlTag) {
 | 
								if (rainbowInfo == null && psiFile is XmlFile && element !is XmlTag) {
 | 
				
			||||||
					element = PsiTreeUtil.findFirstParent(element, true, XML_TAG_PARENT_CONDITION) ?: return@compute null
 | 
									element = PsiTreeUtil.findFirstParent(element, true, XML_TAG_PARENT_CONDITION) ?: return null
 | 
				
			||||||
					rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element] ?: return@compute null
 | 
									rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element] ?: return null
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			if (!element.isValid || !checkBoundary(document, element, highlighter)) {
 | 
								if (!element.isValid || !checkBoundary(document, element, highlighter)) {
 | 
				
			||||||
					null
 | 
									return null
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else {
 | 
					 | 
				
			||||||
					rainbowInfo
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								return rainbowInfo
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		/***
 | 
							/***
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import com.intellij.ide.actions.ToggleZenModeAction
 | 
				
			|||||||
import com.intellij.lang.LanguageParserDefinitions
 | 
					import com.intellij.lang.LanguageParserDefinitions
 | 
				
			||||||
import com.intellij.openapi.editor.Editor
 | 
					import com.intellij.openapi.editor.Editor
 | 
				
			||||||
import com.intellij.openapi.editor.IndentGuideDescriptor
 | 
					import com.intellij.openapi.editor.IndentGuideDescriptor
 | 
				
			||||||
 | 
					import com.intellij.openapi.editor.ex.EditorEx
 | 
				
			||||||
import com.intellij.openapi.editor.ex.util.EditorUtil
 | 
					import com.intellij.openapi.editor.ex.util.EditorUtil
 | 
				
			||||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea
 | 
					import com.intellij.openapi.editor.markup.HighlighterTargetArea
 | 
				
			||||||
import com.intellij.openapi.editor.markup.MarkupModel
 | 
					import com.intellij.openapi.editor.markup.MarkupModel
 | 
				
			||||||
@@ -22,8 +23,8 @@ import com.intellij.openapi.util.TextRange
 | 
				
			|||||||
import com.intellij.psi.PsiFile
 | 
					import com.intellij.psi.PsiFile
 | 
				
			||||||
import com.intellij.psi.tree.TokenSet
 | 
					import com.intellij.psi.tree.TokenSet
 | 
				
			||||||
import com.intellij.util.DocumentUtil
 | 
					import com.intellij.util.DocumentUtil
 | 
				
			||||||
 | 
					import com.intellij.util.containers.IntStack
 | 
				
			||||||
import com.intellij.util.text.CharArrayUtil
 | 
					import com.intellij.util.text.CharArrayUtil
 | 
				
			||||||
import it.unimi.dsi.fastutil.ints.IntArrayList
 | 
					 | 
				
			||||||
import java.lang.StrictMath.abs
 | 
					import java.lang.StrictMath.abs
 | 
				
			||||||
import java.lang.StrictMath.min
 | 
					import java.lang.StrictMath.min
 | 
				
			||||||
import java.util.Collections
 | 
					import java.util.Collections
 | 
				
			||||||
@@ -34,9 +35,11 @@ import java.util.Collections
 | 
				
			|||||||
 * */
 | 
					 * */
 | 
				
			||||||
class RainbowIndentsPass internal constructor(
 | 
					class RainbowIndentsPass internal constructor(
 | 
				
			||||||
	project: Project,
 | 
						project: Project,
 | 
				
			||||||
	private val myEditor: Editor,
 | 
						editor: Editor,
 | 
				
			||||||
	private val myFile: PsiFile,
 | 
						private val myFile: PsiFile,
 | 
				
			||||||
) : TextEditorHighlightingPass(project, myEditor.document, false), DumbAware {
 | 
					) : TextEditorHighlightingPass(project, editor.document, false), DumbAware {
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private val myEditor: EditorEx = editor as EditorEx
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	@Volatile
 | 
						@Volatile
 | 
				
			||||||
	private var myRanges = emptyList<TextRange>()
 | 
						private var myRanges = emptyList<TextRange>()
 | 
				
			||||||
@@ -148,8 +151,8 @@ class RainbowIndentsPass internal constructor(
 | 
				
			|||||||
		calculator.calculate()
 | 
							calculator.calculate()
 | 
				
			||||||
		val lineIndents = calculator.lineIndents
 | 
							val lineIndents = calculator.lineIndents
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		val lines = IntArrayList()
 | 
							val lines = IntStack()
 | 
				
			||||||
		val indents = IntArrayList()
 | 
							val indents = IntStack()
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		lines.push(0)
 | 
							lines.push(0)
 | 
				
			||||||
		indents.push(0)
 | 
							indents.push(0)
 | 
				
			||||||
@@ -158,10 +161,10 @@ class RainbowIndentsPass internal constructor(
 | 
				
			|||||||
			ProgressManager.checkCanceled()
 | 
								ProgressManager.checkCanceled()
 | 
				
			||||||
			val curIndent = abs(lineIndents[line])
 | 
								val curIndent = abs(lineIndents[line])
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			while (!indents.isEmpty && curIndent <= indents.peekInt(0)) {
 | 
								while (!indents.empty() && curIndent <= indents.peek()) {
 | 
				
			||||||
				ProgressManager.checkCanceled()
 | 
									ProgressManager.checkCanceled()
 | 
				
			||||||
				val level = indents.popInt()
 | 
									val level = indents.pop()
 | 
				
			||||||
				val startLine = lines.popInt()
 | 
									val startLine = lines.pop()
 | 
				
			||||||
				if (level > 0) {
 | 
									if (level > 0) {
 | 
				
			||||||
					for (i in startLine until line) {
 | 
										for (i in startLine until line) {
 | 
				
			||||||
						if (level != abs(lineIndents[i])) {
 | 
											if (level != abs(lineIndents[i])) {
 | 
				
			||||||
@@ -181,10 +184,10 @@ class RainbowIndentsPass internal constructor(
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		while (!indents.isEmpty) {
 | 
							while (!indents.empty()) {
 | 
				
			||||||
			ProgressManager.checkCanceled()
 | 
								ProgressManager.checkCanceled()
 | 
				
			||||||
			val level = indents.popInt()
 | 
								val level = indents.pop()
 | 
				
			||||||
			val startLine = lines.popInt()
 | 
								val startLine = lines.pop()
 | 
				
			||||||
			if (level > 0) {
 | 
								if (level > 0) {
 | 
				
			||||||
				descriptors.add(createDescriptor(level, startLine, document.lineCount, lineIndents))
 | 
									descriptors.add(createDescriptor(level, startLine, document.lineCount, lineIndents))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -204,12 +207,38 @@ class RainbowIndentsPass internal constructor(
 | 
				
			|||||||
		return IndentGuideDescriptor(level, sLine, endLine)
 | 
							return IndentGuideDescriptor(level, sLine, endLine)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						private fun findCodeConstructStart(startLine: Int): Int? {
 | 
				
			||||||
 | 
							val document = myEditor.document
 | 
				
			||||||
 | 
							val text = document.immutableCharSequence
 | 
				
			||||||
 | 
							val lineStartOffset = document.getLineStartOffset(startLine)
 | 
				
			||||||
 | 
							val firstNonWsOffset = CharArrayUtil.shiftForward(text, lineStartOffset, " \t")
 | 
				
			||||||
 | 
							val type = PsiUtilBase.getPsiFileAtOffset(myFile, firstNonWsOffset).fileType
 | 
				
			||||||
 | 
							val language = PsiUtilCore.getLanguageAtOffset(myFile, firstNonWsOffset)
 | 
				
			||||||
 | 
							val braceMatcher = BraceMatchingUtil.getBraceMatcher(type, language)
 | 
				
			||||||
 | 
							val iterator = myEditor.highlighter.createIterator(firstNonWsOffset)
 | 
				
			||||||
 | 
							return if (braceMatcher.isLBraceToken(iterator, text, type)) {
 | 
				
			||||||
 | 
								braceMatcher.getCodeConstructStart(myFile, firstNonWsOffset)
 | 
				
			||||||
 | 
							} else null
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private fun findCodeConstructStartLine(startLine: Int): Int {
 | 
				
			||||||
 | 
							val codeConstructStart = findCodeConstructStart(startLine)
 | 
				
			||||||
 | 
							return if (codeConstructStart != null) myEditor.document.getLineNumber(codeConstructStart) else startLine
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	private inner class IndentsCalculator {
 | 
						private inner class IndentsCalculator {
 | 
				
			||||||
		val myComments: MutableMap<String, TokenSet> = HashMap()
 | 
							val myComments: MutableMap<String, TokenSet> = HashMap()
 | 
				
			||||||
		val lineIndents = IntArray(document.lineCount) // negative value means the line is empty (or contains a comment) and indent
 | 
							val lineIndents = IntArray(document.lineCount) // negative value means the line is empty (or contains a comment) and indent
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		// (denoted by absolute value) was deduced from enclosing non-empty lines
 | 
							// (denoted by absolute value) was deduced from enclosing non-empty lines
 | 
				
			||||||
		val myChars = document.charsSequence
 | 
							val myChars: CharSequence
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							init {
 | 
				
			||||||
 | 
								myChars = document.charsSequence
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * Calculates line indents for the [target document][.myDocument].
 | 
							 * Calculates line indents for the [target document][.myDocument].
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +1,19 @@
 | 
				
			|||||||
package com.chylex.intellij.coloredbrackets.indents
 | 
					package com.chylex.intellij.coloredbrackets.indents
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.intellij.codeHighlighting.Pass
 | 
					import com.intellij.codeHighlighting.Pass
 | 
				
			||||||
 | 
					import com.intellij.codeHighlighting.TextEditorHighlightingPass
 | 
				
			||||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
 | 
					import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
 | 
				
			||||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactoryRegistrar
 | 
					import com.intellij.codeHighlighting.TextEditorHighlightingPassFactoryRegistrar
 | 
				
			||||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
 | 
					import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
 | 
				
			||||||
import com.intellij.openapi.editor.Editor
 | 
					import com.intellij.openapi.editor.Editor
 | 
				
			||||||
import com.intellij.openapi.editor.impl.ImaginaryEditor
 | 
					 | 
				
			||||||
import com.intellij.openapi.project.Project
 | 
					import com.intellij.openapi.project.Project
 | 
				
			||||||
import com.intellij.psi.PsiFile
 | 
					import com.intellij.psi.PsiFile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RainbowIndentsPassFactory :
 | 
					class RainbowIndentsPassFactory :
 | 
				
			||||||
	TextEditorHighlightingPassFactoryRegistrar, TextEditorHighlightingPassFactory {
 | 
						TextEditorHighlightingPassFactoryRegistrar, TextEditorHighlightingPassFactory {
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun createHighlightingPass(file: PsiFile, editor: Editor): RainbowIndentsPass? {
 | 
						override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass {
 | 
				
			||||||
		return when (editor) {
 | 
							return RainbowIndentsPass(file.project, editor, file)
 | 
				
			||||||
			is ImaginaryEditor -> null
 | 
					 | 
				
			||||||
			else               -> RainbowIndentsPass(file.project, editor, file)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
 | 
						override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,8 @@
 | 
				
			|||||||
package com.chylex.intellij.coloredbrackets.settings
 | 
					package com.chylex.intellij.coloredbrackets.settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.settings.form.RainbowSettingsForm
 | 
					import com.chylex.intellij.coloredbrackets.settings.form.RainbowSettingsForm
 | 
				
			||||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
 | 
					 | 
				
			||||||
import com.intellij.openapi.options.ConfigurationException
 | 
					import com.intellij.openapi.options.ConfigurationException
 | 
				
			||||||
import com.intellij.openapi.options.SearchableConfigurable
 | 
					import com.intellij.openapi.options.SearchableConfigurable
 | 
				
			||||||
import com.intellij.openapi.project.ProjectManager
 | 
					 | 
				
			||||||
import org.jetbrains.annotations.Nls
 | 
					import org.jetbrains.annotations.Nls
 | 
				
			||||||
import javax.swing.JComponent
 | 
					import javax.swing.JComponent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -47,10 +45,6 @@ class RainbowConfigurable : SearchableConfigurable {
 | 
				
			|||||||
		settings.doNOTRainbowifyBigFiles = settingsForm?.doNOTRainbowifyBigFiles() ?: true
 | 
							settings.doNOTRainbowifyBigFiles = settingsForm?.doNOTRainbowifyBigFiles() ?: true
 | 
				
			||||||
		settings.bigFilesLinesThreshold = settingsForm?.bigFilesLinesThreshold() ?: 1000
 | 
							settings.bigFilesLinesThreshold = settingsForm?.bigFilesLinesThreshold() ?: 1000
 | 
				
			||||||
		settings.rainbowifyPythonKeywords = settingsForm?.rainbowifyPythonKeywords() ?: false
 | 
							settings.rainbowifyPythonKeywords = settingsForm?.rainbowifyPythonKeywords() ?: false
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		ProjectManager.getInstanceIfCreated()?.openProjects?.forEach {
 | 
					 | 
				
			||||||
			DaemonCodeAnalyzer.getInstance(it).restart()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun reset() {
 | 
						override fun reset() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,13 +2,12 @@ package com.chylex.intellij.coloredbrackets.settings
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import com.intellij.openapi.application.ApplicationManager
 | 
					import com.intellij.openapi.application.ApplicationManager
 | 
				
			||||||
import com.intellij.openapi.components.PersistentStateComponent
 | 
					import com.intellij.openapi.components.PersistentStateComponent
 | 
				
			||||||
import com.intellij.openapi.components.SettingsCategory
 | 
					 | 
				
			||||||
import com.intellij.openapi.components.State
 | 
					import com.intellij.openapi.components.State
 | 
				
			||||||
import com.intellij.openapi.components.Storage
 | 
					import com.intellij.openapi.components.Storage
 | 
				
			||||||
import com.intellij.util.xmlb.XmlSerializerUtil
 | 
					import com.intellij.util.xmlb.XmlSerializerUtil.copyBean
 | 
				
			||||||
import org.jetbrains.annotations.Nullable
 | 
					import org.jetbrains.annotations.Nullable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@State(name = "ColoredBracketsSettings", storages = [Storage("colored_brackets.xml")], category = SettingsCategory.UI)
 | 
					@State(name = "ColoredBracketsSettings", storages = [Storage("colored_brackets.xml")])
 | 
				
			||||||
class RainbowSettings : PersistentStateComponent<RainbowSettings> {
 | 
					class RainbowSettings : PersistentStateComponent<RainbowSettings> {
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * default value
 | 
						 * default value
 | 
				
			||||||
@@ -38,7 +37,7 @@ class RainbowSettings : PersistentStateComponent<RainbowSettings> {
 | 
				
			|||||||
	var rainbowifyTagNameInXML = false
 | 
						var rainbowifyTagNameInXML = false
 | 
				
			||||||
	var doNOTRainbowifyTemplateString = false
 | 
						var doNOTRainbowifyTemplateString = false
 | 
				
			||||||
	var doNOTRainbowifyBigFiles = true
 | 
						var doNOTRainbowifyBigFiles = true
 | 
				
			||||||
	var bigFilesLinesThreshold = 100_000
 | 
						var bigFilesLinesThreshold = 1000
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	var languageBlacklist: Set<String> = setOf("hocon", "mxml")
 | 
						var languageBlacklist: Set<String> = setOf("hocon", "mxml")
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@@ -51,7 +50,7 @@ class RainbowSettings : PersistentStateComponent<RainbowSettings> {
 | 
				
			|||||||
	override fun getState() = this
 | 
						override fun getState() = this
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun loadState(state: RainbowSettings) {
 | 
						override fun loadState(state: RainbowSettings) {
 | 
				
			||||||
		XmlSerializerUtil.copyBean(state, this)
 | 
							copyBean(state, this)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	companion object {
 | 
						companion object {
 | 
				
			||||||
@@ -23,7 +23,7 @@ private interface MemoizedCall<in F, out R> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private class MemoizedHandler<F, in K : MemoizedCall<F, R>, out R>(val f: F) {
 | 
					private class MemoizedHandler<F, in K : MemoizedCall<F, R>, out R>(val f: F) {
 | 
				
			||||||
	private val m = Platform.newConcurrentMap<K, R>()
 | 
						private val m = Platform.newConcurrentMap<K, R>()
 | 
				
			||||||
	operator fun invoke(k: K): R = m[k] ?: m.putSafely(k, k(f))
 | 
						operator fun invoke(k: K): R = m[k] ?: run { m.putSafely(k, k(f)) }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private data class MemoizeKey1<out A, R>(val a: A) : MemoizedCall<(A) -> R, R> {
 | 
					private data class MemoizeKey1<out A, R>(val a: A) : MemoizedCall<(A) -> R, R> {
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
package com.chylex.intellij.coloredbrackets.visitor
 | 
					package com.chylex.intellij.coloredbrackets.visitor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.BracePairs.bracePairs
 | 
					import com.chylex.intellij.coloredbrackets.bracePairs
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.BracePairs.braceTypeSet
 | 
					import com.chylex.intellij.coloredbrackets.braceTypeSet
 | 
				
			||||||
import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
 | 
					import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
 | 
				
			||||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
 | 
					import com.intellij.codeInsight.daemon.impl.HighlightVisitor
 | 
				
			||||||
import com.intellij.lang.BracePair
 | 
					import com.intellij.lang.BracePair
 | 
				
			||||||
@@ -9,31 +9,28 @@ import com.intellij.psi.PsiElement
 | 
				
			|||||||
import com.intellij.psi.PsiFile
 | 
					import com.intellij.psi.PsiFile
 | 
				
			||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
 | 
					import com.intellij.psi.impl.source.tree.LeafPsiElement
 | 
				
			||||||
import com.intellij.psi.tree.IElementType
 | 
					import com.intellij.psi.tree.IElementType
 | 
				
			||||||
import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DefaultRainbowVisitor : RainbowHighlightVisitor() {
 | 
					class DefaultRainbowVisitor : RainbowHighlightVisitor() {
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun clone(): HighlightVisitor = DefaultRainbowVisitor()
 | 
						override fun clone(): HighlightVisitor = DefaultRainbowVisitor()
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private var processor: Processor? = null
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	override fun onBeforeAnalyze(file: PsiFile, updateWholeFile: Boolean) {
 | 
					 | 
				
			||||||
		processor = Processor(RainbowSettings.instance)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	override fun visit(element: PsiElement) {
 | 
						override fun visit(element: PsiElement) {
 | 
				
			||||||
		val type = (element as? LeafPsiElement)?.elementType ?: return
 | 
							val type = (element as? LeafPsiElement)?.elementType ?: return
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		val processor = processor!!
 | 
							val settings = RainbowSettings.instance
 | 
				
			||||||
 | 
							val processor = Processor(settings)
 | 
				
			||||||
		val matching = processor.filterPairs(type, element) ?: return
 | 
							val matching = processor.filterPairs(type, element) ?: return
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		val pair = when (matching.size) {
 | 
							val pair =
 | 
				
			||||||
			1    -> matching[0]
 | 
								if (matching.size == 1) {
 | 
				
			||||||
			else -> matching.find { processor.isValidBracket(element, it) } ?: return
 | 
									matching[0]
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									matching.find { processor.isValidBracket(element, it) }
 | 
				
			||||||
 | 
								} ?: return
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		val level = processor.getBracketLevel(element, pair)
 | 
							val level = processor.getBracketLevel(element, pair)
 | 
				
			||||||
		if (processor.settings.isDoNOTRainbowifyTheFirstLevel) {
 | 
							if (settings.isDoNOTRainbowifyTheFirstLevel) {
 | 
				
			||||||
			if (level >= 1) {
 | 
								if (level >= 1) {
 | 
				
			||||||
				rainbowPairs(element, pair, level)
 | 
									rainbowPairs(element, pair, level)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -45,35 +42,13 @@ class DefaultRainbowVisitor : RainbowHighlightVisitor() {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	override fun onAfterAnalyze() {
 | 
					 | 
				
			||||||
		processor = null
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
 | 
						private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
 | 
				
			||||||
		val startElement = element.takeIf { it.elementType == pair.leftBraceType }
 | 
							val startElement = element.takeIf { it.elementType == pair.leftBraceType }
 | 
				
			||||||
		val endElement = element.takeIf { it.elementType == pair.rightBraceType }
 | 
							val endElement = element.takeIf { it.elementType == pair.rightBraceType }
 | 
				
			||||||
		element.setHighlightInfo(element.parent, level, startElement, endElement)
 | 
							element.setHighlightInfo(element.parent, level, startElement, endElement)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	private class Processor(val settings: RainbowSettings) {
 | 
						private class Processor(private val settings: RainbowSettings) {
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		private companion object {
 | 
					 | 
				
			||||||
			private const val CACHE_MISS = (-1).toByte()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		private data class HasBracketsCacheKey(val element: PsiElement, val pair: BracePair) {
 | 
					 | 
				
			||||||
			private val hashCode = (31 * System.identityHashCode(element)) + System.identityHashCode(pair)
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			override fun equals(other: Any?): Boolean {
 | 
					 | 
				
			||||||
				return other is HasBracketsCacheKey && element === other.element && pair === other.pair
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			override fun hashCode(): Int {
 | 
					 | 
				
			||||||
				return hashCode
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		private val hasBracketsCache = Object2ByteOpenHashMap<HasBracketsCacheKey>().apply { defaultReturnValue(CACHE_MISS) }
 | 
					 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		fun getBracketLevel(element: LeafPsiElement, pair: BracePair): Int = iterateBracketParents(element.parent, pair, -1)
 | 
							fun getBracketLevel(element: LeafPsiElement, pair: BracePair): Int = iterateBracketParents(element.parent, pair, -1)
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
@@ -84,19 +59,17 @@ class DefaultRainbowVisitor : RainbowHighlightVisitor() {
 | 
				
			|||||||
			
 | 
								
 | 
				
			||||||
			var nextCount = count
 | 
								var nextCount = count
 | 
				
			||||||
			if (!settings.cycleCountOnAllBrackets) {
 | 
								if (!settings.cycleCountOnAllBrackets) {
 | 
				
			||||||
				if (element.hasBrackets(
 | 
									if (element.haveBrackets(
 | 
				
			||||||
						pair,
 | 
											{ it.elementType() == pair.leftBraceType },
 | 
				
			||||||
						{ it.elementType == pair.leftBraceType },
 | 
											{ it.elementType() == pair.rightBraceType })
 | 
				
			||||||
						{ it.elementType == pair.rightBraceType })
 | 
					 | 
				
			||||||
				) {
 | 
									) {
 | 
				
			||||||
					nextCount++
 | 
										nextCount++
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else {
 | 
								else {
 | 
				
			||||||
				if (element.hasBrackets(
 | 
									if (element.haveBrackets(
 | 
				
			||||||
						pair,
 | 
											{ element.language.braceTypeSet.contains(it.elementType()) },
 | 
				
			||||||
						{ element.language.braceTypeSet.contains(it.elementType) },
 | 
											{ element.language.braceTypeSet.contains(it.elementType()) })
 | 
				
			||||||
						{ element.language.braceTypeSet.contains(it.elementType) })
 | 
					 | 
				
			||||||
				) {
 | 
									) {
 | 
				
			||||||
					nextCount++
 | 
										nextCount++
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -105,27 +78,18 @@ class DefaultRainbowVisitor : RainbowHighlightVisitor() {
 | 
				
			|||||||
			return iterateBracketParents(element.parent, pair, nextCount)
 | 
								return iterateBracketParents(element.parent, pair, nextCount)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		private inline fun PsiElement.hasBrackets(
 | 
							private inline fun PsiElement.haveBrackets(
 | 
				
			||||||
			pair: BracePair,
 | 
								checkLeft: (PsiElement) -> Boolean,
 | 
				
			||||||
			checkLeft: (LeafPsiElement) -> Boolean,
 | 
								checkRight: (PsiElement) -> Boolean,
 | 
				
			||||||
			checkRight: (LeafPsiElement) -> Boolean,
 | 
					 | 
				
			||||||
		): Boolean {
 | 
							): Boolean {
 | 
				
			||||||
			if (this is LeafPsiElement) {
 | 
								if (this is LeafPsiElement) {
 | 
				
			||||||
				return false
 | 
									return false
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			val cacheKey = HasBracketsCacheKey(this, pair)
 | 
					 | 
				
			||||||
			val cacheValue = hasBracketsCache.getByte(cacheKey)
 | 
					 | 
				
			||||||
			if (cacheValue != CACHE_MISS) {
 | 
					 | 
				
			||||||
				return cacheValue == 1.toByte()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			val hasBrackets = run {
 | 
					 | 
				
			||||||
			var findLeftBracket = false
 | 
								var findLeftBracket = false
 | 
				
			||||||
			var findRightBracket = false
 | 
								var findRightBracket = false
 | 
				
			||||||
			var left: PsiElement? = firstChild
 | 
								var left: PsiElement? = firstChild
 | 
				
			||||||
			var right: PsiElement? = lastChild
 | 
								var right: PsiElement? = lastChild
 | 
				
			||||||
				
 | 
					 | 
				
			||||||
			while (left != right && (!findLeftBracket || !findRightBracket)) {
 | 
								while (left != right && (!findLeftBracket || !findRightBracket)) {
 | 
				
			||||||
				val needBreak = left == null || left.nextSibling == right
 | 
									val needBreak = left == null || left.nextSibling == right
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
@@ -147,17 +111,16 @@ class DefaultRainbowVisitor : RainbowHighlightVisitor() {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
				// For https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/830
 | 
								//For https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/830
 | 
				
			||||||
				if (settings.doNOTRainbowifyTemplateString && left?.prevSibling?.textMatches("$") == true) {
 | 
								if (settings.doNOTRainbowifyTemplateString) {
 | 
				
			||||||
					false
 | 
									if (left?.prevSibling?.textMatches("$") == true) return false
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else {
 | 
					 | 
				
			||||||
					findLeftBracket && findRightBracket
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			hasBracketsCache.put(cacheKey, if (hasBrackets) 1.toByte() else 0.toByte())
 | 
								return findLeftBracket && findRightBracket
 | 
				
			||||||
			return hasBrackets
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							private fun PsiElement.elementType(): IElementType? {
 | 
				
			||||||
 | 
								return (this as? LeafPsiElement)?.elementType
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		fun isValidBracket(element: LeafPsiElement, pair: BracePair): Boolean {
 | 
							fun isValidBracket(element: LeafPsiElement, pair: BracePair): Boolean {
 | 
				
			||||||
@@ -197,21 +160,24 @@ class DefaultRainbowVisitor : RainbowHighlightVisitor() {
 | 
				
			|||||||
			val pairs = element.language.bracePairs ?: return null
 | 
								val pairs = element.language.bracePairs ?: return null
 | 
				
			||||||
			val filterBraceType = pairs[type.toString()]
 | 
								val filterBraceType = pairs[type.toString()]
 | 
				
			||||||
			return when {
 | 
								return when {
 | 
				
			||||||
				filterBraceType.isNullOrEmpty()                             -> null
 | 
									filterBraceType.isNullOrEmpty()                             -> {
 | 
				
			||||||
				
 | 
										null
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/198
 | 
									// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/198
 | 
				
			||||||
				element.javaClass.simpleName == "OCMacroForeignLeafElement" -> null
 | 
									element.javaClass.simpleName == "OCMacroForeignLeafElement" -> {
 | 
				
			||||||
 | 
										null
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				settings.isDoNOTRainbowifyBracketsWithoutContent            -> filterBraceType
 | 
									settings.isDoNOTRainbowifyBracketsWithoutContent            -> {
 | 
				
			||||||
 | 
										filterBraceType
 | 
				
			||||||
						.filterNot { it.leftBraceType == type && element.nextSibling?.elementType() == it.rightBraceType }
 | 
											.filterNot { it.leftBraceType == type && element.nextSibling?.elementType() == it.rightBraceType }
 | 
				
			||||||
						.filterNot { it.rightBraceType == type && element.prevSibling?.elementType() == it.leftBraceType }
 | 
											.filterNot { it.rightBraceType == type && element.prevSibling?.elementType() == it.leftBraceType }
 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				else                                                        -> filterBraceType
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
		private fun PsiElement.elementType(): IElementType? {
 | 
									else                                                        -> {
 | 
				
			||||||
			return (this as? LeafPsiElement)?.elementType
 | 
										filterBraceType
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,6 +35,7 @@ abstract class RainbowHighlightVisitor : HighlightVisitor {
 | 
				
			|||||||
		onBeforeAnalyze(file, updateWholeFile)
 | 
							onBeforeAnalyze(file, updateWholeFile)
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			action.run()
 | 
								action.run()
 | 
				
			||||||
 | 
							} catch (e: Throwable) {
 | 
				
			||||||
		} finally {
 | 
							} finally {
 | 
				
			||||||
			onAfterAnalyze()
 | 
								onAfterAnalyze()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -96,8 +97,10 @@ abstract class RainbowHighlightVisitor : HighlightVisitor {
 | 
				
			|||||||
		
 | 
							
 | 
				
			||||||
		private fun fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(fileType: String) =
 | 
							private fun fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(fileType: String) =
 | 
				
			||||||
			fileType != "Haskell" || !isIntelliJHaskellEnabled
 | 
								fileType != "Haskell" || !isIntelliJHaskellEnabled
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private fun PsiElement.getLineCount(): Int {
 | 
					fun PsiElement.getLineCount(): Int {
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		val doc = containingFile?.let { PsiDocumentManager.getInstance(project).getDocument(it) }
 | 
							val doc = containingFile?.let { PsiDocumentManager.getInstance(project).getDocument(it) }
 | 
				
			||||||
		if (doc != null) {
 | 
							if (doc != null) {
 | 
				
			||||||
@@ -114,6 +117,4 @@ abstract class RainbowHighlightVisitor : HighlightVisitor {
 | 
				
			|||||||
	} catch (e: Throwable) {
 | 
						} catch (e: Throwable) {
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -5,40 +5,13 @@
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  <description><![CDATA[
 | 
					  <description><![CDATA[
 | 
				
			||||||
      Fork of the <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets">Rainbow Brackets</a> plugin by <a href="https://github.com/izhangzhihao">izhangzhihao</a>, based on version 6.26.
 | 
					      Fork of the <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets">Rainbow Brackets</a> plugin by <a href="https://github.com/izhangzhihao">izhangzhihao</a>, based on version 6.26.
 | 
				
			||||||
    <br><br>
 | 
					 | 
				
			||||||
    <b>Key Changes</b>
 | 
					 | 
				
			||||||
    <ul>
 | 
					 | 
				
			||||||
      <li>Support for C# (Rider)</li>
 | 
					 | 
				
			||||||
      <li>Support for C++ (Rider, CLion, CLion Nova)</li>
 | 
					 | 
				
			||||||
      <li>Support for Settings Sync</li>
 | 
					 | 
				
			||||||
      <li>Improved highlighting performance</li>
 | 
					 | 
				
			||||||
      <li>Increased default setting for maximum line count from 1K to 100K</li>
 | 
					 | 
				
			||||||
      <li>Fixed service initialization warnings reported by 2024.2+</li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
  ]]></description>
 | 
					  ]]></description>
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  <change-notes><![CDATA[
 | 
					  <change-notes><![CDATA[
 | 
				
			||||||
    <b>Version 1.3.0</b>
 | 
					    <p>1.0.0</p>
 | 
				
			||||||
    <ul>
 | 
					    <ul>
 | 
				
			||||||
      <li>Fixed assertion error caused by missing read lock in indent guide renderer.</li>
 | 
					      <li>Added support for CLion and Rider</li>
 | 
				
			||||||
    </ul>
 | 
					      <li>Fixed service initialization warnings reported by 2024.2+</li>
 | 
				
			||||||
    <b>Version 1.2.0</b>
 | 
					 | 
				
			||||||
    <ul>
 | 
					 | 
				
			||||||
      <li>Fixed not re-highlighting open files after changing settings.</li>
 | 
					 | 
				
			||||||
      <li>Fixed exception when opening certain diff editors.</li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
    <b>Version 1.1.0</b>
 | 
					 | 
				
			||||||
    <ul>
 | 
					 | 
				
			||||||
      <li>Added support for C++ in Rider and CLion Nova.</li>
 | 
					 | 
				
			||||||
      <li>Fixed broken option to not color parentheses without content in C#.</li>
 | 
					 | 
				
			||||||
      <li>Improved highlighting performance.</li>
 | 
					 | 
				
			||||||
      <li>Increased default setting for maximum line count from 1K to 100K.</li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
    <b>Version 1.0.0</b>
 | 
					 | 
				
			||||||
    <ul>
 | 
					 | 
				
			||||||
      <li>Restored support for CLion and Rider.</li>
 | 
					 | 
				
			||||||
      <li>Added support for Settings Sync.</li>
 | 
					 | 
				
			||||||
      <li>Fixed service initialization warnings reported by IJ 2024.2.</li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
  ]]></change-notes>
 | 
					  ]]></change-notes>
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@@ -47,8 +20,7 @@
 | 
				
			|||||||
  <depends optional="true" config-file="JSX.xml">JavaScript</depends>
 | 
					  <depends optional="true" config-file="JSX.xml">JavaScript</depends>
 | 
				
			||||||
  <depends optional="true" config-file="dart-brackets.xml">Dart</depends>
 | 
					  <depends optional="true" config-file="dart-brackets.xml">Dart</depends>
 | 
				
			||||||
  <depends optional="true" config-file="groovy-brackets.xml">org.intellij.groovy</depends>
 | 
					  <depends optional="true" config-file="groovy-brackets.xml">org.intellij.groovy</depends>
 | 
				
			||||||
  <depends optional="true" config-file="cpp-nova-brackets.xml">org.jetbrains.plugins.clion.radler</depends>
 | 
					  <!--<depends optional="true" config-file="csharp-annotator.xml">com.intellij.modules.rider</depends>-->
 | 
				
			||||||
  <depends optional="true" config-file="cpp-rider-brackets.xml">com.intellij.modules.rider</depends>
 | 
					 | 
				
			||||||
  <depends optional="true" config-file="csharp-brackets.xml">com.intellij.modules.rider</depends>
 | 
					  <depends optional="true" config-file="csharp-brackets.xml">com.intellij.modules.rider</depends>
 | 
				
			||||||
  <depends optional="true" config-file="intellij-haskell-annotator.xml">intellij.haskell</depends>
 | 
					  <depends optional="true" config-file="intellij-haskell-annotator.xml">intellij.haskell</depends>
 | 
				
			||||||
  <depends optional="true" config-file="sql-brackets.xml">com.intellij.database</depends>
 | 
					  <depends optional="true" config-file="sql-brackets.xml">com.intellij.database</depends>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user