mirror of
https://github.com/chylex/IntelliJ-Rainbow-Brackets.git
synced 2025-01-30 13:45:59 +01:00
Compare commits
3 Commits
48c8cc73b0
...
74ac5273b9
Author | SHA1 | Date | |
---|---|---|---|
74ac5273b9 | |||
b732020017 | |||
93f5911faf |
@ -9,7 +9,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "com.chylex.intellij.coloredbrackets"
|
group = "com.chylex.intellij.coloredbrackets"
|
||||||
version = "1.1.0"
|
version = "1.2.0"
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
apply(plugin = "org.jetbrains.kotlin.jvm")
|
apply(plugin = "org.jetbrains.kotlin.jvm")
|
||||||
|
@ -9,21 +9,27 @@ 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 : EditorNotifications.Provider<EditorNotificationPanel>() {
|
class RainbowifyBanner : EditorNotificationProvider {
|
||||||
override fun getKey(): Key<EditorNotificationPanel> = KEY
|
override fun collectNotificationData(project: Project, file: VirtualFile): Function<in FileEditor, out JComponent?> {
|
||||||
|
return Function { createNotificationPanel(project, file) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor, project: Project): EditorNotificationPanel? {
|
private fun createNotificationPanel(project: Project, file: VirtualFile): EditorNotificationPanel? {
|
||||||
val settings = RainbowSettings.instance
|
val settings = RainbowSettings.instance
|
||||||
|
|
||||||
if (!settings.isRainbowEnabled) {
|
if (!settings.isRainbowEnabled) {
|
||||||
if (settings.suppressDisabledCheck) return null
|
if (settings.suppressDisabledCheck) {
|
||||||
|
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)
|
||||||
@ -41,7 +47,9 @@ class RainbowifyBanner : EditorNotifications.Provider<EditorNotificationPanel>()
|
|||||||
|
|
||||||
val psiFile = file.toPsiFile(project)
|
val psiFile = file.toPsiFile(project)
|
||||||
if (psiFile != null && !checkForBigFile(psiFile)) {
|
if (psiFile != null && !checkForBigFile(psiFile)) {
|
||||||
if (settings.suppressBigFileCheck) return null
|
if (settings.suppressBigFileCheck) {
|
||||||
|
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)
|
||||||
@ -61,7 +69,9 @@ class RainbowifyBanner : EditorNotifications.Provider<EditorNotificationPanel>()
|
|||||||
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) return null
|
if (settings.suppressBlackListCheck) {
|
||||||
|
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)
|
||||||
@ -81,14 +91,10 @@ class RainbowifyBanner : EditorNotifications.Provider<EditorNotificationPanel>()
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
private fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
|
||||||
private val KEY = Key.create<EditorNotificationPanel>("RainbowifyBanner")
|
val label: Ref<HyperlinkLabel> = Ref.create()
|
||||||
|
label.set(createActionLabel(labelText) {
|
||||||
fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
|
callback(label.get())
|
||||||
val label: Ref<HyperlinkLabel> = Ref.create()
|
})
|
||||||
label.set(createActionLabel(labelText) {
|
|
||||||
callback(label.get())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ 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
|
||||||
@ -23,8 +22,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
|
||||||
@ -35,11 +34,9 @@ import java.util.Collections
|
|||||||
* */
|
* */
|
||||||
class RainbowIndentsPass internal constructor(
|
class RainbowIndentsPass internal constructor(
|
||||||
project: Project,
|
project: Project,
|
||||||
editor: Editor,
|
private val myEditor: Editor,
|
||||||
private val myFile: PsiFile,
|
private val myFile: PsiFile,
|
||||||
) : TextEditorHighlightingPass(project, editor.document, false), DumbAware {
|
) : TextEditorHighlightingPass(project, myEditor.document, false), DumbAware {
|
||||||
|
|
||||||
private val myEditor: EditorEx = editor as EditorEx
|
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var myRanges = emptyList<TextRange>()
|
private var myRanges = emptyList<TextRange>()
|
||||||
@ -151,8 +148,8 @@ class RainbowIndentsPass internal constructor(
|
|||||||
calculator.calculate()
|
calculator.calculate()
|
||||||
val lineIndents = calculator.lineIndents
|
val lineIndents = calculator.lineIndents
|
||||||
|
|
||||||
val lines = IntStack()
|
val lines = IntArrayList()
|
||||||
val indents = IntStack()
|
val indents = IntArrayList()
|
||||||
|
|
||||||
lines.push(0)
|
lines.push(0)
|
||||||
indents.push(0)
|
indents.push(0)
|
||||||
@ -161,10 +158,10 @@ class RainbowIndentsPass internal constructor(
|
|||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
val curIndent = abs(lineIndents[line])
|
val curIndent = abs(lineIndents[line])
|
||||||
|
|
||||||
while (!indents.empty() && curIndent <= indents.peek()) {
|
while (!indents.isEmpty && curIndent <= indents.peekInt(0)) {
|
||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
val level = indents.pop()
|
val level = indents.popInt()
|
||||||
val startLine = lines.pop()
|
val startLine = lines.popInt()
|
||||||
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])) {
|
||||||
@ -184,10 +181,10 @@ class RainbowIndentsPass internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!indents.empty()) {
|
while (!indents.isEmpty) {
|
||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
val level = indents.pop()
|
val level = indents.popInt()
|
||||||
val startLine = lines.pop()
|
val startLine = lines.popInt()
|
||||||
if (level > 0) {
|
if (level > 0) {
|
||||||
descriptors.add(createDescriptor(level, startLine, document.lineCount, lineIndents))
|
descriptors.add(createDescriptor(level, startLine, document.lineCount, lineIndents))
|
||||||
}
|
}
|
||||||
@ -207,38 +204,12 @@ 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: CharSequence
|
val myChars = document.charsSequence
|
||||||
|
|
||||||
init {
|
|
||||||
myChars = document.charsSequence
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates line indents for the [target document][.myDocument].
|
* Calculates line indents for the [target document][.myDocument].
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
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): TextEditorHighlightingPass {
|
override fun createHighlightingPass(file: PsiFile, editor: Editor): RainbowIndentsPass? {
|
||||||
return RainbowIndentsPass(file.project, editor, file)
|
return when (editor) {
|
||||||
|
is ImaginaryEditor -> null
|
||||||
|
else -> RainbowIndentsPass(file.project, editor, file)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
||||||
|
@ -18,18 +18,23 @@
|
|||||||
]]></description>
|
]]></description>
|
||||||
|
|
||||||
<change-notes><![CDATA[
|
<change-notes><![CDATA[
|
||||||
<b>1.1.0</b>
|
<b>Version 1.2.0</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Added support for C++ in Rider and CLion Nova</li>
|
<li>Fixed not re-highlighting open files after changing settings.</li>
|
||||||
<li>Fixed broken option to not color parentheses without content in C#</li>
|
<li>Fixed exception when opening certain diff editors.</li>
|
||||||
<li>Improved highlighting performance</li>
|
|
||||||
<li>Increased default setting for maximum line count from 1K to 100K</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<b>1.0.0</b>
|
<b>Version 1.1.0</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Restored support for CLion and Rider</li>
|
<li>Added support for C++ in Rider and CLion Nova.</li>
|
||||||
<li>Added support for Settings Sync</li>
|
<li>Fixed broken option to not color parentheses without content in C#.</li>
|
||||||
<li>Fixed service initialization warnings reported by IJ 2024.2+</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>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user