Compare commits
17 Commits
9491251f81
...
main
Author | SHA1 | Date | |
---|---|---|---|
74ac5273b9
|
|||
b732020017
|
|||
93f5911faf
|
|||
48c8cc73b0
|
|||
5b5cf0aeb5
|
|||
e2e50e15a9
|
|||
072011caee
|
|||
ad617451c7
|
|||
0e379b3a45
|
|||
92baf7cad5
|
|||
02f46987b4
|
|||
80f19cc47b
|
|||
f4b6bc7637
|
|||
2977a08009
|
|||
ec78647a17
|
|||
4ad30ca3dc
|
|||
06765e9d7f
|
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
128
.github/CODE_OF_CONDUCT.md
vendored
@@ -1,128 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
2
.gitignore
vendored
@@ -1,7 +1,5 @@
|
||||
/.idea/*
|
||||
!/.idea/icon*.png
|
||||
!/.idea/runConfigurations
|
||||
|
||||
/.gradle/
|
||||
/build/
|
||||
/libs/
|
||||
|
2
.idea/runConfigurations/Run_IDEA.xml
generated
@@ -10,7 +10,7 @@
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value=":idea:runIde" />
|
||||
<option value=":runIde" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
|
24
.idea/vcs.xml
generated
@@ -1,24 +0,0 @@
|
||||
<?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>
|
742
CHANGELOG.md
@@ -1,742 +0,0 @@
|
||||
## Change log
|
||||
|
||||
<p>2022.3.1</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2529">#2529: [paid][C#] fix:
|
||||
compatibility issues with Rider 2022.3.</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2533">#2533: [paid][C#] fix:
|
||||
colours incorrect when using "Cycle count on all brackets".</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2354">#2354: [paid][C#] fix:
|
||||
colours incorrect when using "Cycle count on all brackets".</a></li>
|
||||
<li>Fix many compatibility issues with IntelliJ platform 2022.3.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.26</p>
|
||||
<ul>
|
||||
<li>Bump dependencies.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.25</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/pull/2484">#2484 Add configurable threshold
|
||||
for number of lines for big files.</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.24</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2478">#2478 Scope highlighting not
|
||||
working with Hiberbee Theme(and other themes).</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.23</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2465">#2465 Improved performance of
|
||||
`annotateUtil`.</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.22</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2408">#2408 Support Code With Me
|
||||
client(Doesn't even need to be installed on the client side)</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.21</p>
|
||||
<ul>
|
||||
<li>Handle exceptions in `RainbowHighlightVisitor.analyze()`</a></li>
|
||||
<li>Cleanup 201.* stuff</a></li>
|
||||
<li>Refactoring</a></li>
|
||||
<li>Mirror changes from https://github.com/JetBrains/intellij-community</a></li>
|
||||
<li>Using textMatches instead of text to avoid expensive traverses the whole PSI tree & format code</a></li>
|
||||
<li>Add support for rainbowify Python keywords</li>
|
||||
<li>Compatible with DataSpell</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.20</p>
|
||||
<ul>
|
||||
<li>Handle exceptions in `RainbowHighlightVisitor.analyze()`</a></li>
|
||||
<li>Cleanup 201.* stuff</a></li>
|
||||
<li>Refactoring</a></li>
|
||||
<li>Mirror changes from https://github.com/JetBrains/intellij-community</a></li>
|
||||
<li>Using textMatches instead of text to avoid expensive traverses the whole PSI tree & format code</a></li>
|
||||
<li>Add support for rainbowify Python keywords</li>
|
||||
<li>Compatible with DataSpell</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.19</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2280">#2280: [SQL] the END keyword
|
||||
is improperly detected as closing a BEGIN scope when the END actually closes a CASE.</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/1993">#1993: Change the default
|
||||
color schema in light theme.</a></li>
|
||||
<li>Nashorn Engine removed, compatible with JDK15+, tested with OpenJDK 17-ea+24 on MacBook Pro (16-inch, 2019) &
|
||||
IntelliJ IDEA 2021.2 Build #IU-212.4638.7</li>
|
||||
<li>Compatible with HUAWEI DevEco Studio</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.18</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2037">#2037: Wrong coloring in
|
||||
generic `<` after comparison operator `<`.</a>
|
||||
</li>
|
||||
<li>Error report removed.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.17</p>
|
||||
<ul>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/pull/1068">#1068: @keeganwitt Add
|
||||
language exclusions to settings (closes #1046) (#1068) </a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/1067">#1067: Don't rainbowify big
|
||||
files notification annoying</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/1057">#1057: Wrong coloring in
|
||||
lambda expressions with braces</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/497">#497: Add `<` & `>` support
|
||||
for C# </a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/191">#191: C# Razor Pages
|
||||
(.cshtml) Support </a></li>
|
||||
<li>Deprecated API usage removed.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.16</p>
|
||||
<ul>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/458">#458: Color Parentheses
|
||||
In Go Template</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/988">#988: (@Grandmother) minor:
|
||||
fix mispell in notification message</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/973">#973: File text mismatch</a>
|
||||
</li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/497">#497: C# in Rider - only
|
||||
squiggly brackets are rainbowified </a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.15</p>
|
||||
<ul>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/897">#897: Initial support for
|
||||
Pug/Jade Language</a></li>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/830">#830: New option "Do NOT
|
||||
rainbowify template string"</a></li>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/784">#784: Disable rainbowify
|
||||
on big files(>1000 lines for now)</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/851">#851: Rainbowify tag name
|
||||
doesn't works in JSX</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/875">#875: cannot create
|
||||
configurable component</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/799">#799 #817: Wrong element
|
||||
created by ASTFactory</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.13</p>
|
||||
<ul>
|
||||
<li>Make as a non-dynamic plugin, so it now requires restart.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.12.1</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/516">#516: Add option to raibowify
|
||||
tag name of XML/HTML(disabled by default)</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/279">#279: Hide update
|
||||
notification on any click & Disable update notification support</a></li>
|
||||
<li>Feature: Rainbowify XML/HTML tag name.</li>
|
||||
<li>Feature: Upgrade to kotlin 1.4.10.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.12</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/279">#279: Hide update
|
||||
notification on any click & Disable update notification support</a></li>
|
||||
<li>Feature: Rainbowify XML/HTML tag name.</li>
|
||||
<li>Feature: Upgrade to kotlin 1.4.10.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.11</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/481">#481: rainbow-brackets does
|
||||
not support bash shell properly(for BashSupport Pro and Shell Script)</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/485">#485: Incorrect coloriziong
|
||||
after lambda in C#</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/242">#242: Colorization is applied
|
||||
only to left parenthesis in for loop(C#) </a></li>
|
||||
<li>Feature: C# support switch to new implementation.</li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/476">#476: Cannot create class
|
||||
com.github.izhangzhihao.rainbow.brackets.provider.SqlProvider</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.10</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/480">#480: Plugin Incompatibility:
|
||||
Android Studio 4.2 Alpha 8</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.9.1</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/445">#445: No working on Android
|
||||
Studio canary 4.2</a></li>
|
||||
<li>Some bug fixs and code refactorings</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.7</p>
|
||||
<ul>
|
||||
<li>Fix NPE</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.6</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/436">#436: Duplicated indent
|
||||
guides in 2020.2 EAP</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.5</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/410">#410:
|
||||
ArrayIndexOutOfBoundsException</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/429">#429:
|
||||
NullPointerException</a></li>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/427">#427: Colorizing angle
|
||||
brackets for Typescript generics</a></li>
|
||||
<li>Some refactoring!</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.4</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/420">#420: Exceptions in random
|
||||
color generator</a></li>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/423">#423: Don't rainbow php and
|
||||
echo tag</a></li>
|
||||
<li>Fix anonymous feedback</li>
|
||||
<li>Some refactoring!</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.3</p>
|
||||
<ul>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/417">#417: Disable Rainbow
|
||||
Indents in Zen mode</a></li>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/227">#227: Coloring for angle
|
||||
bracket for C++ code</a></li>
|
||||
<li>Fix some exceptions and refactoring!</li>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/214">#214: New color generator
|
||||
to generate your color schema</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
|
||||
<p>6.2</p>
|
||||
<ul>
|
||||
<li>Fix <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/410">#410:
|
||||
ArrayIndexOutOfBoundsException when number of colors to less than 5</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.1</p>
|
||||
<ul>
|
||||
<li>First release of 2020.1 and Java 11!</li>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/235">#235: support SQL begin
|
||||
end colorization</a></li>
|
||||
<li>Notification improved</li>
|
||||
<li>Error report improved</li>
|
||||
<li>Deprecated API usage removed</li>
|
||||
<li>Initial support for <a
|
||||
href="https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/dynamic_plugins.html">dynamic
|
||||
plugin</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.0</p>
|
||||
<ul>
|
||||
<li>First release of 2020.1 and Java 11!</li>
|
||||
<li>Feature <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/235">#235: support SQL begin
|
||||
end colorization</a></li>
|
||||
<li>Notification improved</li>
|
||||
<li>Error report improved</li>
|
||||
<li>Deprecated API usage removed</li>
|
||||
<li>Initial support for <a
|
||||
href="https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/dynamic_plugins.html">dynamic
|
||||
plugin</a></li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.35</p>
|
||||
<ul>
|
||||
<li>Final release of 2017.2 and Java 8! start from the next release, we will build against with 2020.1 and Java 11
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.34</p>
|
||||
<ul>
|
||||
<li>Compatible with Material Theme UI Plugin</li>
|
||||
<li>Fix typo</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.33</p>
|
||||
<ul>
|
||||
<li>Fix ArrayIndexOutOfBoundsException</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.32</p>
|
||||
<ul>
|
||||
<li>Feature #391: Support cycle color on all bracket types(new option `Cycle count on all bracket types`)</li>
|
||||
<li>Fix ArrayIndexOutOfBoundsException</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.31</p>
|
||||
<ul>
|
||||
<li>#187 Feature: Ability to increase the number of colours in the IDE</li>
|
||||
<li>#247 Feature: Add a button to apply the color code to all kind of brackets</li>
|
||||
<li>#374 Feature: Add support for IntelliJ-Haskell</li>
|
||||
<li>Fix #54: Disable rainbow for mxml files</li>
|
||||
<li>Fix typo</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.30</p>
|
||||
<ul>
|
||||
<li>Rollback indent guides</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.29</p>
|
||||
<ul>
|
||||
<li>Compatible color schema with the latest version of material-theme-jetbrains</li>
|
||||
<li>Fix some errors</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.28</p>
|
||||
<ul>
|
||||
<li>Improve error report</li>
|
||||
<li>Fix some errors with Nginx plugin</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.27</p>
|
||||
<ul>
|
||||
<li>Improve rainbow indent guide lines</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.26</p>
|
||||
<ul>
|
||||
<li>Improve error report.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.25</p>
|
||||
<ul>
|
||||
<li>Fix #259 Runtime error in rainbow indent guide lines.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.24</p>
|
||||
<ul>
|
||||
<li>Fix #252 Runtime error in rainbow indent guide lines.</li>
|
||||
<li>Fix #254 Nginx support is been disabled from now on.</li>
|
||||
<li>Re-enable anonymous feedback</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.23</p>
|
||||
<ul>
|
||||
<li>#164 #251 New feature: Rainbow indent guide lines(experimental), Thanks https://github.com/YiiGuxing !</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.22</p>
|
||||
<ul>
|
||||
<li>Fix #243 #180, allow users custom matched brace by setting `overrideMatchedBraceAttributes = false`</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.21</p>
|
||||
<ul>
|
||||
<li>#65 [Scope Highlighting] now the effects will not been removed after shortcut released, users could press the
|
||||
key `ESC` to do this. There also have an option `Press any key to remove the highlighting effects`</li>
|
||||
<li>Refactoring & Remove dead code</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.20</p>
|
||||
<ul>
|
||||
<li>#233 Option to not rainbowify brackets of the first level</li>
|
||||
<li>#234 Color is displayed with wrong order in C# code</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.19</p>
|
||||
<ul>
|
||||
<li>Fix notification.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.18</p>
|
||||
<ul>
|
||||
<li>Add notification for custom your own rainbow colors.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.17</p>
|
||||
<ul>
|
||||
<li>More color options for squiggly brackets before cycle(#215).</li>
|
||||
<li>NullPointerException in while analyse code(#216).</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.16</p>
|
||||
<ul>
|
||||
<li>Add shiny new icon.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.15</p>
|
||||
<ul>
|
||||
<li>Fix support for kotlin scheme attribute "KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW".</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.14</p>
|
||||
<ul>
|
||||
<li>Remove deprecated API usages.</li>
|
||||
<li>Refactoring.</li>
|
||||
<li>Added Dart to the supported languages list(#205).</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.13</p>
|
||||
<ul>
|
||||
<li>Fix macro support of Clang(#198)</li>
|
||||
<li>Remove red-variation colors from default configuration(#192)</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.12</p>
|
||||
<ul>
|
||||
<li>Intellij-rainbow-brackets now support C# language(#6)!</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.11</p>
|
||||
<ul>
|
||||
<li>Now you could disable rainbow brackets for specific languages, see more info <a
|
||||
href="https://github.com/izhangzhihao/intellij-rainbow-brackets#disable-rainbow-brackets-for-specific-languages">here</a>.
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.10</p>
|
||||
<ul>
|
||||
<li>New color settings page!!! Thanks this PR(#179) from https://github.com/YiiGuxing.</li>
|
||||
<li>See the new settings page in Settings/Preferences > Editor > Color Scheme > Rainbow Brackets.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.9.1</p>
|
||||
<ul>
|
||||
<li>Fix wrong background color on a light theme of "MATCHED_BRACE_ATTRIBUTES"(#155).</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.9</p>
|
||||
<ul>
|
||||
<li>Rainbow Kotlin lambda expression arrow(#142).</li>
|
||||
<li>Experimental feature: Highlight Kotlin label(#143).</li>
|
||||
<li>Override "MATCHED_BRACE_ATTRIBUTES".</li>
|
||||
<li>Improve configs & docs.</li>
|
||||
<li>Cleanup temp code & deprecated code.</li>
|
||||
<li>Remove anonymous feedback.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.8.3</p>
|
||||
<ul>
|
||||
<li>Improve anonymous feedback</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.8.2</p>
|
||||
<ul>
|
||||
<li>Override kotlin plugin setting `KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW` to empty so that we could
|
||||
rainbowify multiple level lambda expressions.
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.8.1</p>
|
||||
<ul>
|
||||
<li>Fix #67: Can't find resource for bundle java.util.PropertyResourceBundle, key version</li>
|
||||
<li>Improve anonymous feedback</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.8</p>
|
||||
<ul>
|
||||
<li>Feature #52 Flat out all text other than brackets on key (Alt + Button3) press. (via pull request#63)
|
||||
</li>
|
||||
<li>Feature #61 Change Highlight Current Scope Keymap to Ctrl + Button3 (Windows & Linux) or Meta+ Button3
|
||||
(Mac) (via pull request#63)
|
||||
</li>
|
||||
<li>Add anonymous feedback support</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.7.1</p>
|
||||
<ul>
|
||||
<li>Fix #60 :Exception in v5.7</li>
|
||||
<li>Experimental feature: Highlight current scope when Ctrl(Windows & Linux)/Meta(Mac) key pressed (feature
|
||||
#37 / pull request#59)
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.7</p>
|
||||
<ul>
|
||||
<li>Experimental feature: Highlight current scope when Ctrl(Windows & Linux)/Meta(Mac) key pressed (feature
|
||||
#37 / pull request#59)
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.6</p>
|
||||
<ul>
|
||||
<li>Performance improvement</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.5</p>
|
||||
<ul>
|
||||
<li>Fix #53 The closing brackets or keywords are not highlighted (Ruby & PHP)</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.4</p>
|
||||
<ul>
|
||||
<li>Fix #53 The closing brackets or keywords are not highlighted (Ruby & PHP)</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.3</p>
|
||||
<ul>
|
||||
<li>Improve angle bracket support for Groovy</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.2</p>
|
||||
<ul>
|
||||
<li>#48 Performance improvement</li>
|
||||
<li>#49 Fix images size</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.1</p>
|
||||
<ul>
|
||||
<li>#39 Enable rainbow html in js</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.0</p>
|
||||
<ul>
|
||||
<li>Finally, intellij-rainbow-brackets released version 5.0 with all RC features & bug fix</li>
|
||||
<li><b>Thanks for https://github.com/YiiGuxing, which helps move this plugin from `Annotator` to
|
||||
`HighlightVisitor`!</b></li>
|
||||
<li>Check more info at <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/pull/25">here</a>
|
||||
</li>
|
||||
<li>From 5.x series we didn't need specific implementations like java/scala/kotlin specific implementations
|
||||
in 3.x series anymore!
|
||||
</li>
|
||||
<br />
|
||||
<li>#13 Add test for dart support & add `DartAngleBracketProvider` for support dart angle brackets</li>
|
||||
<li>#18 where to customize brackets color? See the config guide in <a
|
||||
href="https://github.com/izhangzhihao/intellij-rainbow-brackets#Config-brackets-colors">here</a>
|
||||
</li>
|
||||
<li>Add test for #39</li>
|
||||
<li>#38 Add support for JSX (React)</li>
|
||||
<li>Fix #27 Settings no longer works</li>
|
||||
<li>#30 Adjust color: remove red, purple from color palettes, add some material design color to color
|
||||
palettes.
|
||||
</li>
|
||||
<li>#32 Add version info in setting page</li>
|
||||
<li>#31 Fix 'Enablement of round brackets enables all but angle brackets'</li>
|
||||
<li>#10 #2 Add setting to disable rainbow-ify brackets without content</li>
|
||||
<li>Show update notification after plugin updated</li>
|
||||
<li>Add a lot of tests</li>
|
||||
<li>Convert all java code to kotlin</li>
|
||||
<br />
|
||||
<li>And with much more features not documented in release notes.</li>
|
||||
<li>NOTE: this version are build against with IU-2017.2.7, but verified by IC-2017.2</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.0-RC4</p>
|
||||
<ul>
|
||||
<li>#10 #2 Add setting to disable rainbow-ify brackets without content</li>
|
||||
<li>Show update notification after plugin updated</li>
|
||||
<li>Add a lot of tests</li>
|
||||
<li>Convert all java code to kotlin</li>
|
||||
<li>NOTE: this version are build against with IU-2017.2.7, but verified by IC-2017.2</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.0-RC3</p>
|
||||
<ul>
|
||||
<li>#32 Add version info in setting page</li>
|
||||
<li>#31 Fix 'Enablement of round brackets enables all but angle brackets(#31)'</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.0-RC2</p>
|
||||
<ul>
|
||||
<li>#30 Adjust color: remove red, purple from color palettes, add some material design color to color
|
||||
palettes.
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.0-RC1</p>
|
||||
<ul>
|
||||
<li>Fix #27 Settings no longer works</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>5.0-RC0</p>
|
||||
<ul>
|
||||
<li>This is the first RC releases on 5.x series!</li>
|
||||
<li><b>Thanks for https://github.com/YiiGuxing, which helps move this plugin from `Annotator` to
|
||||
`HighlightVisitor`!</b></li>
|
||||
<li>Check more info at https://github.com/izhangzhihao/intellij-rainbow-brackets/pull/25</li>
|
||||
<li>This RC release has fantastic compatibility with previous release(3.x series).</li>
|
||||
<li>From 5.x series we didn't need specific implementations like java/scala/kotlin specific implementations
|
||||
in 3.x series anymore!
|
||||
</li>
|
||||
<li>And with much more features not documented in release notes.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>3.1</p>
|
||||
<ul>
|
||||
<li>Add a specific implementation for PHP language</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>3.0</p>
|
||||
<ul>
|
||||
<li>Version 3.0 has been released, with all RC features & bug fix</li>
|
||||
<li>Fix #23 Inconsistent colors</li>
|
||||
<li>Fix #21 Wrong bracket colorization based on spaces</li>
|
||||
<li>Fix #19 Kotlin expression inside string bug</li>
|
||||
<li>Fix #12 Symbol less ">" is considered as a bracket even without leading "<"< /li>
|
||||
<li>Fix #11 Same level brackets should have same color</li>
|
||||
<li>And much more!</li>
|
||||
<li>Add specific implement for java/kotlin/scala/javascript</li>
|
||||
<li>Add example to help people add specific implementation for specific language!</li>
|
||||
<li>Check out README.md on github https://github.com/izhangzhihao/intellij-rainbow-brackets</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>3.0-RC5</p>
|
||||
<ul>
|
||||
<li>Adjust colors for default light theme. Thanks to https://github.com/YiiGuxing</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>3.0-RC4</p>
|
||||
<ul>
|
||||
<li>Add specific implement for java/kotlin/scala</li>
|
||||
<li>So now in java/kotlin/scala same level brackets should have same color.</li>
|
||||
<li>Fix: #19:Kotlin expression inside string bug</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>3.0-RC2</p>
|
||||
<ul>
|
||||
<li>Remove option for enable/disable rainbow for HTML/XML</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>3.0-RC1</p>
|
||||
<ul>
|
||||
<li>Add new setting page to control what/how to colorify:</li>
|
||||
<li>1. Add option to Enable/disable rainbow</li>
|
||||
<li>2. Add option to Enable rainbow for any unsupported languages</li>
|
||||
<li>3. Add option to Enable/disable rainbow for HTML/XML</li>
|
||||
<li>4. Add option to Enable/disable rainbow for round brackets</li>
|
||||
<li>5. Add option to Enable/disable rainbow for squiggly brackets</li>
|
||||
<li>6. Add option to Enable/disable rainbow for square brackets</li>
|
||||
<li>7. Add option to Enable/disable rainbow for angle brackets</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>2.6</p>
|
||||
<ul>
|
||||
<li>Add support for salesforce apex language, thanks for https://github.com/onisuly</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>2.5</p>
|
||||
<ul>
|
||||
<li>Fix Rust support, thanks for https://github.com/fst3a</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>2.4</p>
|
||||
<ul>
|
||||
<li>Add support for SQL</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>2.3</p>
|
||||
<ul>
|
||||
<li>Add support for HTML/XML</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>2.2</p>
|
||||
<ul>
|
||||
<li>Add support for C#</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>2.1</p>
|
||||
<ul>
|
||||
<li>New identifiable colors</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>2.0</p>
|
||||
<ul>
|
||||
<li>Rainbowify brackets faster!</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>1.1</p>
|
||||
<ul>
|
||||
<li>Support IntelliJ IDEA based IDEs version 14 and above</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>1.0</p>
|
||||
<ul>
|
||||
<li>Initial release</li>
|
||||
</ul>
|
15
README.md
@@ -1,9 +1,12 @@
|
||||
# Rainbow Brackets
|
||||
# Colored Brackets
|
||||
|
||||
This is a fork of the [🌈Rainbow Brackets](https://github.com/izhangzhihao/intellij-rainbow-brackets) plugin by <a href="https://github.com/izhangzhihao">izhangzhihao</a>.
|
||||
This is a fork of the [🌈Rainbow Brackets](https://github.com/izhangzhihao/intellij-rainbow-brackets) plugin by [izhangzhihao](https://github.com/izhangzhihao), based on version 6.26.
|
||||
|
||||
## Changes
|
||||
## Key Changes
|
||||
|
||||
- Added support for Rider
|
||||
- Restructured the project for easier support of Rider and CLion
|
||||
- Removed post-update notification
|
||||
- Support for C# (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+
|
||||
|
148
build.gradle.kts
@@ -1,109 +1,129 @@
|
||||
@file:Suppress("SpellCheckingInspection")
|
||||
@file:Suppress("ConvertLambdaToReference")
|
||||
|
||||
import org.jetbrains.intellij.IntelliJPluginExtension
|
||||
import org.jetbrains.intellij.tasks.BuildPluginTask
|
||||
import org.jetbrains.intellij.tasks.BuildSearchableOptionsTask
|
||||
import org.jetbrains.intellij.tasks.PatchPluginXmlTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import kotlin.io.path.Path
|
||||
|
||||
plugins {
|
||||
idea
|
||||
kotlin("jvm")
|
||||
id("org.jetbrains.intellij") apply false
|
||||
id("org.jetbrains.intellij")
|
||||
}
|
||||
|
||||
group = "com.chylex.intellij.rainbowbrackets"
|
||||
version = "6.26-chylex-3"
|
||||
group = "com.chylex.intellij.coloredbrackets"
|
||||
version = "1.2.0"
|
||||
|
||||
val ideVersion = "2023.2.2"
|
||||
val ideBuild = "232"
|
||||
|
||||
idea {
|
||||
module {
|
||||
excludeDirs.add(file("gradle"))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":clion"))
|
||||
implementation(project(":idea"))
|
||||
implementation(project(":rider"))
|
||||
}
|
||||
|
||||
subprojects {
|
||||
allprojects {
|
||||
apply(plugin = "org.jetbrains.kotlin.jvm")
|
||||
apply(plugin = "org.jetbrains.intellij")
|
||||
|
||||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven(url = "https://www.jetbrains.com/intellij-repository/releases")
|
||||
maven(url = "https://www.jetbrains.com/intellij-repository/snapshots")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("io.kotest:kotest-assertions-core:5.5.5")
|
||||
intellij {
|
||||
version.set("2023.3")
|
||||
updateSinceUntilBuild.set(false)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
configure<IntelliJPluginExtension> {
|
||||
version.set(ideVersion)
|
||||
updateSinceUntilBuild.set(false)
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.freeCompilerArgs = listOf(
|
||||
"-Xjvm-default=all"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
tasks.buildSearchableOptions {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
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 {
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("io.kotest:kotest-assertions-core:5.8.0") {
|
||||
exclude(group = "org.jetbrains.kotlin")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.patchPluginXml {
|
||||
sinceBuild.set("233")
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnit()
|
||||
}
|
||||
|
||||
tasks.getByName<BuildSearchableOptionsTask>("buildSearchableOptions") {
|
||||
enabled = false
|
||||
}
|
||||
tasks.buildPlugin {
|
||||
val projectName = rootProject.name
|
||||
val instrumentedJarName = "instrumented-$projectName-$version"
|
||||
|
||||
tasks.getByName<PatchPluginXmlTask>("patchPluginXml") {
|
||||
sinceBuild.set(ideBuild)
|
||||
}
|
||||
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")
|
||||
|
||||
tasks.getByName<BuildPluginTask>("buildPlugin") {
|
||||
eachFile {
|
||||
name = name.replaceFirst("instrumented-", "instrumented-RainbowBrackets-")
|
||||
relativePath.segments[0] = "RainbowBrackets"
|
||||
val newName = name.replace("instrumented-", "${instrumentedJarName}-")
|
||||
val newPath = relativePath.segments.dropLast(3).plus(newName)
|
||||
relativePath = RelativePath(true, *newPath.toTypedArray())
|
||||
}
|
||||
|
||||
includeEmptyDirs = false
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<Zip>("buildPlugin") {
|
||||
group = "intellij"
|
||||
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"),
|
||||
)
|
||||
|
||||
for (project in listOf("clion", "idea", "rider")) {
|
||||
val buildPlugin = project(":$project").tasks.getByName("buildPlugin")
|
||||
val outputs = buildPlugin.outputs.files.map(::zipTree)
|
||||
val jarFiles = zipTree(outputs.files.singleFile)
|
||||
|
||||
dependsOn(buildPlugin)
|
||||
|
||||
from(outputs) {
|
||||
include("RainbowBrackets/lib/instrumented-RainbowBrackets-$project-$version.jar")
|
||||
}
|
||||
|
||||
if (project == "idea") {
|
||||
from(outputs) {
|
||||
include("RainbowBrackets/lib/searchableOptions-$version.jar")
|
||||
for (expectedPath in expectedPaths) {
|
||||
val found = jarFiles.find { it.toPath().endsWith(expectedPath) }
|
||||
checkNotNull(found) { "Expected path not found: $expectedPath" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destinationDirectory = layout.buildDirectory.dir("distributions")
|
||||
}
|
||||
|
@@ -1,16 +1,13 @@
|
||||
plugins {
|
||||
id("org.jetbrains.intellij")
|
||||
}
|
||||
|
||||
intellij {
|
||||
type.set("CL")
|
||||
|
||||
plugins.set(listOf(
|
||||
// Built-in
|
||||
"cidr-base-plugin"
|
||||
"cidr-base-plugin",
|
||||
//"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.
|
||||
))
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":idea"))
|
||||
implementation(rootProject)
|
||||
}
|
||||
|
@@ -0,0 +1,8 @@
|
||||
package com.chylex.intellij.coloredbrackets.provider
|
||||
|
||||
import com.intellij.lang.BracePair
|
||||
import com.jetbrains.cidr.lang.parser.OCLexerTokenTypes
|
||||
|
||||
class OCBracePairProvider : BracePairProvider {
|
||||
override fun pairs(): List<BracePair> = listOf(BracePair(OCLexerTokenTypes.LT, OCLexerTokenTypes.GT, false))
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.provider
|
||||
|
||||
import com.intellij.lang.BracePair
|
||||
import com.jetbrains.cidr.lang.parser.OCLexerTokenTypes
|
||||
|
||||
class OCBracePairProvider : BracePairProvider {
|
||||
override fun pairs(): List<BracePair> = listOf(BracePair(OCLexerTokenTypes.LT, OCLexerTokenTypes.GT, false))
|
||||
}
|
10
clion/src/main/resources/META-INF/cpp-nova-brackets.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<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,6 +1,6 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||
<bracePairProvider language="ObjectiveC"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.OCBracePairProvider"/>
|
||||
implementationClass="com.chylex.intellij.coloredbrackets.provider.OCBracePairProvider" />
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
@@ -1,2 +1 @@
|
||||
org.gradle.parallel=true
|
||||
kotlin.stdlib.default.dependency=false
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
14
gradlew
vendored
@@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -202,11 +202,11 @@ fi
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
1
idea/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/build/
|
@@ -1,33 +0,0 @@
|
||||
plugins {
|
||||
id("org.jetbrains.intellij")
|
||||
}
|
||||
|
||||
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:232.8660.129", // https://plugins.jetbrains.com/plugin/6351-dart/versions/stable
|
||||
"Pythonid:232.9921.47", // https://plugins.jetbrains.com/plugin/631-python/versions
|
||||
"com.jetbrains.php:232.9921.55", // https://plugins.jetbrains.com/plugin/6610-php/versions
|
||||
"com.jetbrains.sh:232.8660.88", // https://plugins.jetbrains.com/plugin/13122-shell-script/versions
|
||||
"org.intellij.scala:2023.2.23", // https://plugins.jetbrains.com/plugin/1347-scala/versions
|
||||
"org.jetbrains.plugins.go-template:232.9921.89", // https://plugins.jetbrains.com/plugin/10581-go-template/versions
|
||||
"org.jetbrains.plugins.ruby:232.9921.47", // https://plugins.jetbrains.com/plugin/1293-ruby/versions
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
tasks.buildSearchableOptions {
|
||||
enabled = true
|
||||
}
|
@@ -1,82 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.provider.BracePairProvider
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.memoize
|
||||
import com.intellij.codeInsight.highlighting.BraceMatchingUtil
|
||||
import com.intellij.lang.BracePair
|
||||
import com.intellij.lang.CompositeLanguage
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.LanguageBraceMatching
|
||||
import com.intellij.lang.LanguageExtension
|
||||
import com.intellij.lang.PairedBraceMatcher
|
||||
import com.intellij.psi.tree.IElementType
|
||||
|
||||
object BracePairs {
|
||||
|
||||
private val providers = LanguageExtension<BracePairProvider>("com.chylex.intellij.rainbowbrackets.bracePairProvider")
|
||||
|
||||
private val bracePairs =
|
||||
Language.getRegisteredLanguages()
|
||||
.map { language ->
|
||||
if (language is CompositeLanguage) {
|
||||
return@map language.displayName to null
|
||||
}
|
||||
|
||||
val pairs =
|
||||
LanguageBraceMatching.INSTANCE.forLanguage(language)?.pairs.let {
|
||||
if (it == null || it.isEmpty()) {
|
||||
language.associatedFileType
|
||||
?.let { fileType -> BraceMatchingUtil.getBraceMatcher(fileType, language) as? PairedBraceMatcher }
|
||||
?.pairs
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
val pairsList = providers.forLanguage(language)?.pairs()?.let {
|
||||
if (pairs != null && pairs.isNotEmpty()) {
|
||||
it.toMutableSet().apply { addAll(pairs) }
|
||||
} else {
|
||||
it
|
||||
}
|
||||
} ?: pairs?.toList()
|
||||
|
||||
val braceMap: MutableMap<String, MutableList<BracePair>> = mutableMapOf()
|
||||
|
||||
val blackSet = providers.forLanguage(language)?.blackList()?.map { it.toString() }?.toSet()
|
||||
|
||||
pairsList
|
||||
?.filter {
|
||||
if (blackSet != null) {
|
||||
!blackSet.contains(it.toString())
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
?.map { listOf(Pair(it.leftBraceType.toString(), it), Pair(it.rightBraceType.toString(), it)) }
|
||||
?.flatten()
|
||||
?.forEach { it ->
|
||||
val bracePairs = braceMap[it.first]
|
||||
if (bracePairs == null) {
|
||||
braceMap[it.first] = mutableListOf(it.second)
|
||||
} else {
|
||||
bracePairs.add(it.second)
|
||||
}
|
||||
}
|
||||
|
||||
language.displayName to braceMap
|
||||
}
|
||||
.toMap()
|
||||
|
||||
fun getBracePairs(language: Language): MutableMap<String, MutableList<BracePair>>? = bracePairs[language.displayName]
|
||||
|
||||
private fun getBraceTypeSetOf(language: Language): Set<IElementType> = getBracePairs(language)?.values?.flatten()?.map { it -> listOf(it.leftBraceType, it.rightBraceType) }?.flatten()?.toSet() ?: emptySet()
|
||||
|
||||
val braceTypeSet: (Language) -> Set<IElementType> = { language: Language -> getBraceTypeSetOf(language) }.memoize()
|
||||
}
|
||||
|
||||
inline val Language.bracePairs: MutableMap<String, MutableList<BracePair>>?
|
||||
get() = BracePairs.getBracePairs(this)
|
||||
|
||||
inline val Language.braceTypeSet: Set<IElementType>
|
||||
get() = BracePairs.braceTypeSet(this)
|
@@ -1,216 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.memoize
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.editor.colors.TextAttributesScheme
|
||||
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme
|
||||
import com.intellij.openapi.editor.markup.EffectType
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.ui.JBColor
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import java.awt.Color
|
||||
import java.awt.Font
|
||||
|
||||
object RainbowHighlighter {
|
||||
|
||||
val DEFAULT_KOTLIN_LABEL_COLOR = JBColor(0x4a86e8, 0x467cda)
|
||||
|
||||
const val NAME_ROUND_BRACKETS = "Round Brackets"
|
||||
const val NAME_SQUARE_BRACKETS = "Square Brackets"
|
||||
const val NAME_SQUIGGLY_BRACKETS = "Squiggly Brackets"
|
||||
const val NAME_ANGLE_BRACKETS = "Angle Brackets"
|
||||
|
||||
private const val KEY_ROUND_BRACKETS = "ROUND_BRACKETS_RAINBOW_COLOR"
|
||||
private const val KEY_SQUARE_BRACKETS = "SQUARE_BRACKETS_RAINBOW_COLOR"
|
||||
private const val KEY_SQUIGGLY_BRACKETS = "SQUIGGLY_BRACKETS_RAINBOW_COLOR"
|
||||
private const val KEY_ANGLE_BRACKETS = "ANGLE_BRACKETS_RAINBOW_COLOR"
|
||||
|
||||
private val roundBrackets: CharArray = charArrayOf('(', ')')
|
||||
private val squareBrackets: CharArray = charArrayOf('[', ']')
|
||||
private val squigglyBrackets: CharArray = charArrayOf('{', '}')
|
||||
private val angleBrackets: CharArray = charArrayOf('<', '>')
|
||||
|
||||
private val settings = RainbowSettings.instance
|
||||
|
||||
private val roundBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||
createRainbowAttributesKeys(KEY_ROUND_BRACKETS, settings.numberOfColors)
|
||||
private val squareBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||
createRainbowAttributesKeys(KEY_SQUARE_BRACKETS, settings.numberOfColors)
|
||||
private val squigglyBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||
createRainbowAttributesKeys(KEY_SQUIGGLY_BRACKETS, settings.numberOfColors)
|
||||
private val angleBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||
createRainbowAttributesKeys(KEY_ANGLE_BRACKETS, settings.numberOfColors)
|
||||
|
||||
private val rainbowElement: HighlightInfoType = HighlightInfoType
|
||||
.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, DefaultLanguageHighlighterColors.CONSTANT)
|
||||
|
||||
private val PsiElement.isRoundBracket get() = roundBrackets.any { textContains(it) }
|
||||
private val PsiElement.isSquareBracket get() = squareBrackets.any { textContains(it) }
|
||||
private val PsiElement.isSquigglyBracket get() = squigglyBrackets.any { textContains(it) }
|
||||
private val PsiElement.isAngleBracket get() = angleBrackets.any { textContains(it) }
|
||||
|
||||
private fun createRainbowAttributesKeys(keyName: String, size: Int): Array<TextAttributesKey> {
|
||||
return generateSequence(0) { it + 1 }
|
||||
.map { TextAttributesKey.createTextAttributesKey("$keyName$it") }
|
||||
.take(size)
|
||||
.toList()
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
fun getRainbowAttributesKeys(rainbowName: String): Array<TextAttributesKey> {
|
||||
return when (rainbowName) {
|
||||
NAME_ROUND_BRACKETS -> roundBracketsRainbowColorKeys
|
||||
NAME_SQUARE_BRACKETS -> squareBracketsRainbowColorKeys
|
||||
NAME_SQUIGGLY_BRACKETS -> squigglyBracketsRainbowColorKeys
|
||||
NAME_ANGLE_BRACKETS -> angleBracketsRainbowColorKeys
|
||||
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Meta properties(SchemeMetaInfo) should be used.
|
||||
fun isRainbowEnabled(rainbowName: String): Boolean {
|
||||
return when (rainbowName) {
|
||||
NAME_ROUND_BRACKETS -> settings.isEnableRainbowRoundBrackets
|
||||
NAME_SQUARE_BRACKETS -> settings.isEnableRainbowSquareBrackets
|
||||
NAME_SQUIGGLY_BRACKETS -> settings.isEnableRainbowSquigglyBrackets
|
||||
NAME_ANGLE_BRACKETS -> settings.isEnableRainbowAngleBrackets
|
||||
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Meta properties(SchemeMetaInfo) should be used.
|
||||
fun setRainbowEnabled(rainbowName: String, enabled: Boolean) {
|
||||
when (rainbowName) {
|
||||
NAME_ROUND_BRACKETS -> settings.isEnableRainbowRoundBrackets = enabled
|
||||
NAME_SQUARE_BRACKETS -> settings.isEnableRainbowSquareBrackets = enabled
|
||||
NAME_SQUIGGLY_BRACKETS -> settings.isEnableRainbowSquigglyBrackets = enabled
|
||||
NAME_ANGLE_BRACKETS -> settings.isEnableRainbowAngleBrackets = enabled
|
||||
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
||||
}
|
||||
}
|
||||
|
||||
fun isDarkEditor() = EditorColorsManager.getInstance().isDarkEditor
|
||||
|
||||
fun getRainbowColorByLevel(colorsScheme: TextAttributesScheme, rainbowName: String, level: Int): TextAttributesKey {
|
||||
val ind = level % settings.numberOfColors
|
||||
if (settings.useColorGenerator) {
|
||||
return memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
||||
}
|
||||
val key = getRainbowAttributesKeys(rainbowName).getOrNull(ind)
|
||||
return try {
|
||||
val result = colorsScheme.getAttributes(key)
|
||||
if (key == null || result == null || result.foregroundColor == null) {
|
||||
memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
||||
} else {
|
||||
key
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER") // we use parameter as cache key
|
||||
private fun generateColor(isDark: Boolean, rainbowName: String, level: Int): TextAttributesKey {
|
||||
if (!settings.customColorGeneratorOption.isNullOrBlank()) {
|
||||
return genByOption(settings.customColorGeneratorOption!!, rainbowName, level)
|
||||
}
|
||||
if (isDark) {
|
||||
@Language("JSON") val darkOption = """{"luminosity": "light"}"""
|
||||
return genByOption(darkOption, rainbowName, level)
|
||||
}
|
||||
@Language("JSON") val lightOption = """{"luminosity": "dark"}"""
|
||||
return genByOption(lightOption, rainbowName, level)
|
||||
}
|
||||
|
||||
private fun genByOption(option: String, rainbowName: String, level: Int) =
|
||||
com.github.izhangzhihao.rainbow.brackets.util.create("$rainbowName-$level",
|
||||
TextAttributes(randomColor(option), null, null, null, 0))
|
||||
|
||||
val memGetRainbowColorByLevel = { isDark: Boolean, rainbowName: String, level: Int -> generateColor(isDark, rainbowName, level) }.memoize()
|
||||
|
||||
@TestOnly
|
||||
fun getBrackets(): CharArray = roundBrackets + squareBrackets + squigglyBrackets + angleBrackets
|
||||
|
||||
@TestOnly
|
||||
fun getRainbowColor(rainbowName: String, level: Int): Color? {
|
||||
return getRainbowColorByLevel(EditorColorsManager.getInstance().globalScheme, rainbowName, level).defaultAttributes.foregroundColor
|
||||
}
|
||||
|
||||
private fun getTextAttributes(colorsScheme: TextAttributesScheme,
|
||||
element: PsiElement,
|
||||
level: Int): TextAttributesKey? {
|
||||
if (!settings.isRainbowEnabled) {
|
||||
return null
|
||||
}
|
||||
|
||||
val rainbowName = when {
|
||||
settings.applyColorsOfRoundForAllBrackets -> NAME_ROUND_BRACKETS
|
||||
element.isRoundBracket -> if (settings.isEnableRainbowRoundBrackets) NAME_ROUND_BRACKETS else null
|
||||
element.isSquareBracket -> if (settings.isEnableRainbowSquareBrackets) NAME_SQUARE_BRACKETS else null
|
||||
element.isSquigglyBracket -> if (settings.isEnableRainbowSquigglyBrackets) NAME_SQUIGGLY_BRACKETS else null
|
||||
element.isAngleBracket -> if (settings.isEnableRainbowAngleBrackets) NAME_ANGLE_BRACKETS else null
|
||||
else -> NAME_ROUND_BRACKETS
|
||||
} ?: return null
|
||||
|
||||
return getRainbowColorByLevel(colorsScheme, rainbowName, level)
|
||||
}
|
||||
|
||||
fun getHighlightInfo(colorsScheme: TextAttributesScheme, element: PsiElement, level: Int)
|
||||
: HighlightInfo? = getTextAttributes(colorsScheme, element, level)
|
||||
?.let { attr ->
|
||||
HighlightInfo
|
||||
.newHighlightInfo(rainbowElement)
|
||||
.textAttributes(attr)
|
||||
.range(element)
|
||||
.create()
|
||||
}
|
||||
|
||||
|
||||
private val KEY_HTML_CODE: TextAttributesKey by lazy { TextAttributesKey.createTextAttributesKey("HTML_CODE") }
|
||||
private val KEY_KOTLIN_LABEL: TextAttributesKey by lazy { TextAttributesKey.createTextAttributesKey("KOTLIN_LABEL") }
|
||||
private val KEY_MATCHED_BRACE_ATTRIBUTES: TextAttributesKey by lazy {
|
||||
TextAttributesKey.createTextAttributesKey("MATCHED_BRACE_ATTRIBUTES")
|
||||
}
|
||||
private val KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW: TextAttributesKey by lazy {
|
||||
TextAttributesKey.createTextAttributesKey("KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW")
|
||||
}
|
||||
|
||||
|
||||
fun fixHighlighting(scheme: EditorColorsScheme = EditorColorsManager.getInstance().globalScheme) {
|
||||
// html code
|
||||
scheme.setInherited(KEY_HTML_CODE, !settings.isRainbowifyHTMLInsideJS)
|
||||
|
||||
// kotlin label
|
||||
val kotlinLabelColor = DEFAULT_KOTLIN_LABEL_COLOR.takeUnless { settings.isRainbowifyKotlinLabel }
|
||||
val kotlinLabel = TextAttributes(kotlinLabelColor, null, null, EffectType.BOXED, Font.PLAIN)
|
||||
scheme.setAttributes(KEY_KOTLIN_LABEL, kotlinLabel)
|
||||
|
||||
// matched brace
|
||||
if (settings.isOverrideMatchedBraceAttributes) {
|
||||
val matchedBraceAttributes = TextAttributes(null, JBColor(0x99ccbb, 0x3b514d), null, EffectType.BOXED, Font.BOLD)
|
||||
scheme.setAttributes(KEY_MATCHED_BRACE_ATTRIBUTES, matchedBraceAttributes)
|
||||
}
|
||||
|
||||
if (settings.isRainbowifyKotlinFunctionLiteralBracesAndArrow) {
|
||||
scheme.setAttributes(KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW,
|
||||
TextAttributes(null, null, null, EffectType.BOXED, Font.BOLD))
|
||||
} else {
|
||||
scheme.setAttributes(KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW,
|
||||
//TODO: default foregroundColor ???
|
||||
TextAttributes(JBColor(0x89ddff, 0x89ddff), null, null, EffectType.BOXED, Font.BOLD))
|
||||
}
|
||||
}
|
||||
|
||||
private fun EditorColorsScheme.setInherited(key: TextAttributesKey, inherited: Boolean) {
|
||||
setAttributes(key, if (inherited) AbstractColorsScheme.INHERITED_ATTRS_MARKER else TextAttributes())
|
||||
}
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiElement
|
||||
import java.awt.Color
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
data class RainbowInfo(var level: Int, var color: Color) {
|
||||
private var _startElement: WeakReference<PsiElement>? = null
|
||||
private var _endElement: WeakReference<PsiElement>? = null
|
||||
|
||||
var startElement: PsiElement?
|
||||
get() = _startElement?.get()
|
||||
set(value) {
|
||||
_startElement = value?.let { WeakReference(it) }
|
||||
}
|
||||
|
||||
val startOffset get() = startElement?.textRange?.startOffset ?: -1
|
||||
|
||||
var endElement: PsiElement?
|
||||
get() = _endElement?.get()
|
||||
set(value) {
|
||||
_endElement = value?.let { WeakReference(it) }
|
||||
}
|
||||
|
||||
val endOffset get() = endElement?.textRange?.endOffset ?: -1
|
||||
|
||||
fun containsOffset(offset: Int): Boolean {
|
||||
val startElement = startElement ?: return false
|
||||
val endElement = endElement ?: return false
|
||||
val startOffset = startElement.textRange.startOffset
|
||||
val endOffset = endElement.textRange.endOffset
|
||||
|
||||
return offset in startOffset..endOffset
|
||||
}
|
||||
|
||||
companion object {
|
||||
val RAINBOW_INFO_KEY: Key<RainbowInfo> = Key.create("RAINBOW_INFO")
|
||||
}
|
||||
}
|
@@ -1,93 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowConfigurable
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.memoizedFileExtension
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.toPsiFile
|
||||
import com.github.izhangzhihao.rainbow.brackets.visitor.RainbowHighlightVisitor.Companion.checkForBigFile
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.actions.ShowSettingsUtilImpl
|
||||
import com.intellij.openapi.fileEditor.FileEditor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.ui.EditorNotificationPanel
|
||||
import com.intellij.ui.EditorNotifications
|
||||
import com.intellij.ui.HyperlinkLabel
|
||||
|
||||
class RainbowifyBanner : EditorNotifications.Provider<EditorNotificationPanel>() {
|
||||
override fun getKey(): Key<EditorNotificationPanel> = KEY
|
||||
|
||||
override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor, project: Project): EditorNotificationPanel? {
|
||||
|
||||
if (!RainbowSettings.instance.isRainbowEnabled) {
|
||||
if (RainbowSettings.instance.suppressDisabledCheck) return null
|
||||
return EditorNotificationPanel().apply {
|
||||
text("Rainbow Brackets is now disabled")
|
||||
icon(AllIcons.General.GearPlain)
|
||||
createComponentActionLabel("got it, don't show again") {
|
||||
RainbowSettings.instance.suppressDisabledCheck = true
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
|
||||
createComponentActionLabel("enable Rainbow Brackets") {
|
||||
RainbowSettings.instance.isRainbowEnabled = true
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val psiFile = file.toPsiFile(project)
|
||||
if (psiFile != null && !checkForBigFile(psiFile)) {
|
||||
if (RainbowSettings.instance.suppressBigFileCheck) return null
|
||||
return EditorNotificationPanel().apply {
|
||||
text("Rainbowify is disabled for files > " + RainbowSettings.instance.bigFilesLinesThreshold + " lines")
|
||||
icon(AllIcons.General.InspectionsEye)
|
||||
createComponentActionLabel("got it, don't show again") {
|
||||
RainbowSettings.instance.suppressBigFileCheck = true
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
|
||||
createComponentActionLabel("open settings") {
|
||||
ShowSettingsUtilImpl.showSettingsDialog(project, RainbowConfigurable.ID, "")
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
RainbowSettings.instance.languageBlacklist.contains(file.fileType.name) ||
|
||||
RainbowSettings.instance.languageBlacklist.contains(memoizedFileExtension(file.name))
|
||||
) {
|
||||
if (RainbowSettings.instance.suppressBlackListCheck) return null
|
||||
return EditorNotificationPanel().apply {
|
||||
text("Rainbowify is disabled because the language/file extension is in the black list")
|
||||
icon(AllIcons.General.InspectionsEye)
|
||||
|
||||
createComponentActionLabel("got it, don't show again") {
|
||||
RainbowSettings.instance.suppressBlackListCheck = true
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
|
||||
createComponentActionLabel("open setting") {
|
||||
ShowSettingsUtilImpl.showSettingsDialog(project, RainbowConfigurable.ID, "")
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val KEY = Key.create<EditorNotificationPanel>("RainbowifyBanner")
|
||||
|
||||
fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
|
||||
val label: Ref<HyperlinkLabel> = Ref.create()
|
||||
label.set(createActionLabel(labelText) {
|
||||
callback(label.get())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.github.izhangzhihao.rainbow.brackets.color.Luminosity
|
||||
import com.github.izhangzhihao.rainbow.brackets.color.fromString
|
||||
import java.awt.Color
|
||||
|
||||
val mapper: ObjectMapper by lazy { jacksonObjectMapper() }
|
||||
|
||||
fun randomColor(options: String): Color {
|
||||
val ops: Map<String, String> = mapper.readValue(options)
|
||||
return com.github.izhangzhihao.rainbow.brackets.color.randomColor(
|
||||
fromString(ops.getOrDefault("hue", "random")),
|
||||
Luminosity.valueOf(ops.getOrDefault("luminosity", "random"))
|
||||
)
|
||||
}
|
@@ -1,96 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.action
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.editor.textarea.TextComponentEditor
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import java.awt.event.FocusEvent
|
||||
import java.awt.event.FocusListener
|
||||
import java.awt.event.KeyAdapter
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
|
||||
abstract class AbstractScopeHighlightingAction : AnAction() {
|
||||
|
||||
final override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabledAndVisible = e.editor.let { it != null && it !is TextComponentEditor }
|
||||
}
|
||||
|
||||
final override fun actionPerformed(e: AnActionEvent) {
|
||||
val editor = e.editor ?: return
|
||||
val project = editor.project ?: return
|
||||
val psiFile = project.let { PsiDocumentManager.getInstance(it).getPsiFile(editor.document) } ?: return
|
||||
val offset = editor.caretModel.offset
|
||||
val rainbowInfo = psiFile.findRainbowInfoAt(offset) ?: return
|
||||
val highlightManager = HighlightManager.getInstance(project)
|
||||
val highlighters = editor.addHighlighter(highlightManager, rainbowInfo)
|
||||
|
||||
editor.highlightingDisposer?.dispose()
|
||||
if (highlighters.isNotEmpty()) {
|
||||
editor.highlightingDisposer = HighlightingDisposer(editor) {
|
||||
editor.highlightingDisposer = null
|
||||
highlighters.forEach { highlightManager.removeSegmentHighlighter(editor, it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun Editor.addHighlighter(highlightManager: HighlightManager,
|
||||
rainbowInfo: RainbowInfo): Collection<RangeHighlighter>
|
||||
|
||||
private class HighlightingDisposer(private val editor: Editor,
|
||||
private val disposeAction: () -> Unit) : KeyAdapter(), FocusListener {
|
||||
|
||||
init {
|
||||
editor.contentComponent.let {
|
||||
it.addFocusListener(this)
|
||||
it.addKeyListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
disposeAction()
|
||||
editor.contentComponent.let {
|
||||
it.removeFocusListener(this)
|
||||
it.removeKeyListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun focusGained(e: FocusEvent) = Unit
|
||||
override fun focusLost(e: FocusEvent) = Unit
|
||||
override fun keyReleased(e: KeyEvent) = Unit
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val HIGHLIGHTING_DISPOSER_KEY: Key<HighlightingDisposer> = Key.create("HIGHLIGHTING_DISPOSER_KEY")
|
||||
|
||||
private var Editor.highlightingDisposer: HighlightingDisposer?
|
||||
get() = HIGHLIGHTING_DISPOSER_KEY[this]
|
||||
set(value) {
|
||||
HIGHLIGHTING_DISPOSER_KEY[this] = value
|
||||
}
|
||||
|
||||
private val AnActionEvent.editor: Editor? get() = CommonDataKeys.EDITOR.getData(dataContext)
|
||||
|
||||
private fun PsiElement.getRainbowInfo(offset: Int): RainbowInfo? {
|
||||
return RainbowInfo.RAINBOW_INFO_KEY[this]?.takeIf { it.containsOffset(offset) }
|
||||
}
|
||||
|
||||
private fun PsiFile.findRainbowInfoAt(offset: Int): RainbowInfo? {
|
||||
var element = findElementAt(offset)
|
||||
while (element != null) {
|
||||
element.getRainbowInfo(offset)?.let { return it }
|
||||
element = element.parent
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.action
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.alphaBlend
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.editor.markup.EffectType
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import java.awt.Font
|
||||
import java.util.LinkedList
|
||||
|
||||
|
||||
class ScopeHighlightingAction : AbstractScopeHighlightingAction() {
|
||||
|
||||
override fun Editor.addHighlighter(highlightManager: HighlightManager,
|
||||
rainbowInfo: RainbowInfo): Collection<RangeHighlighter> {
|
||||
val defaultBackground = EditorColorsManager.getInstance().globalScheme.defaultBackground
|
||||
val background = rainbowInfo.color.alphaBlend(defaultBackground, 0.2f)
|
||||
val attributes = TextAttributes(null, background, rainbowInfo.color, EffectType.BOXED, Font.PLAIN)
|
||||
val highlighters = LinkedList<RangeHighlighter>()
|
||||
highlightManager.addRangeHighlight(this,
|
||||
rainbowInfo.startOffset,
|
||||
rainbowInfo.endOffset,
|
||||
attributes, //create("ScopeHighlightingAction", attributes),
|
||||
false, //hideByTextChange
|
||||
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
||||
highlighters)
|
||||
|
||||
return highlighters
|
||||
}
|
||||
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.action
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.alphaBlend
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.editor.markup.EffectType
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import java.awt.Color
|
||||
import java.awt.Font
|
||||
import java.util.LinkedList
|
||||
|
||||
class ScopeOutsideHighlightingRestrainAction : AbstractScopeHighlightingAction() {
|
||||
|
||||
override fun Editor.addHighlighter(highlightManager: HighlightManager,
|
||||
rainbowInfo: RainbowInfo): Collection<RangeHighlighter> {
|
||||
val defaultBackground = EditorColorsManager.getInstance().globalScheme.defaultBackground
|
||||
val background = Color.GRAY.alphaBlend(defaultBackground, 0.05f)
|
||||
val foreground = Color.GRAY.alphaBlend(defaultBackground, 0.55f)
|
||||
val attributes = TextAttributes(foreground, background, background, EffectType.BOXED, Font.PLAIN)
|
||||
val highlighters = LinkedList<RangeHighlighter>()
|
||||
|
||||
val startOffset = rainbowInfo.startOffset
|
||||
if (startOffset > 0) {
|
||||
highlightManager.addRangeHighlight(this,
|
||||
0,
|
||||
startOffset,
|
||||
attributes, //create("ScopeOutsideHighlightingRestrainAction", attributes),
|
||||
false, //hideByTextChange
|
||||
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
||||
highlighters)
|
||||
}
|
||||
|
||||
val endOffset = rainbowInfo.endOffset
|
||||
val lastOffset = document.textLength
|
||||
if (endOffset < lastOffset) {
|
||||
highlightManager.addRangeHighlight(this,
|
||||
endOffset,
|
||||
lastOffset,
|
||||
attributes, //create("ScopeOutsideHighlightingRestrainAction", attributes),
|
||||
false, //hideByTextChange
|
||||
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
||||
highlighters)
|
||||
}
|
||||
|
||||
return highlighters
|
||||
}
|
||||
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.annotator
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.Annotator
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.editor.markup.EffectType
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassBody
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtLabeledExpression
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import java.awt.Font
|
||||
|
||||
|
||||
class KotlinLabelAnnotator : Annotator {
|
||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||
if (!RainbowSettings.instance.isRainbowifyKotlinLabel) {
|
||||
return
|
||||
}
|
||||
|
||||
val target: PsiElement
|
||||
var refElement: PsiElement?
|
||||
when (element) {
|
||||
is KtLabelReferenceExpression -> {
|
||||
if ((element.lastChild as? LeafPsiElement)?.elementType == KtTokens.AT) {
|
||||
return
|
||||
}
|
||||
|
||||
target = element
|
||||
refElement = try {
|
||||
element.reference?.resolve()
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
|
||||
refElement = when (refElement) {
|
||||
is KtBlockExpression,
|
||||
is KtFunctionLiteral -> refElement
|
||||
is KtFunction -> refElement.lastChild.takeIf { it is KtBlockExpression }
|
||||
is KtClass -> refElement.lastChild.takeIf { it is KtClassBody }
|
||||
is KtCallExpression,
|
||||
is KtLambdaExpression -> PsiTreeUtil.findChildOfType(refElement, KtFunctionLiteral::class.java)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
is KtLabeledExpression -> {
|
||||
target = element.firstChild.firstChild.takeIf { it is KtLabelReferenceExpression } ?: return
|
||||
refElement = element.lastChild.let {
|
||||
when (it) {
|
||||
is KtBlockExpression,
|
||||
is KtFunctionLiteral -> it
|
||||
is KtCallExpression,
|
||||
is KtLambdaExpression -> PsiTreeUtil.findChildOfType(it, KtFunctionLiteral::class.java)
|
||||
else -> null
|
||||
}
|
||||
} ?: return
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
|
||||
refElement
|
||||
.let { RainbowInfo.RAINBOW_INFO_KEY[it]?.color ?: RainbowHighlighter.DEFAULT_KOTLIN_LABEL_COLOR }
|
||||
.let {
|
||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||
.range(target)
|
||||
.textAttributes(com.github.izhangzhihao.rainbow.brackets.util.create(
|
||||
"rainbow-kotlin-label",
|
||||
TextAttributes(it, null, null, EffectType.BOXED, Font.PLAIN)
|
||||
))
|
||||
.create()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.annotator
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.Annotator
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.editor.markup.EffectType
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import java.awt.Font
|
||||
|
||||
|
||||
class KotlinLambdaExpressionArrowAnnotator : Annotator {
|
||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||
if ((element as? LeafPsiElement)?.elementType == KtTokens.ARROW) {
|
||||
RainbowInfo.RAINBOW_INFO_KEY[element.parent]?.color?.let {
|
||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||
.range(element)
|
||||
.textAttributes(
|
||||
com.github.izhangzhihao.rainbow.brackets.util.create(
|
||||
"rainbow-kotlin-arrow",
|
||||
TextAttributes(it, null, null, EffectType.BOXED, Font.PLAIN)
|
||||
)
|
||||
)
|
||||
.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,115 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.annotator
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter.NAME_ANGLE_BRACKETS
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter.NAME_ROUND_BRACKETS
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter.NAME_SQUARE_BRACKETS
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter.NAME_SQUIGGLY_BRACKETS
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter.getRainbowColorByLevel
|
||||
import com.github.izhangzhihao.rainbow.brackets.annotator.RainbowUtils.annotateUtil
|
||||
import com.github.izhangzhihao.rainbow.brackets.annotator.RainbowUtils.settings
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.Annotator
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
|
||||
class RainbowAnnotator : Annotator {
|
||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||
if (settings.isRainbowEnabled && element is LeafPsiElement) {
|
||||
if (!settings.applyColorsOfRoundForAllBrackets) {
|
||||
if (settings.isEnableRainbowRoundBrackets) annotateUtil(element, holder, "(", ")", NAME_ROUND_BRACKETS)
|
||||
if (settings.isEnableRainbowSquareBrackets) annotateUtil(element, holder, "[", "]", NAME_SQUARE_BRACKETS)
|
||||
if (settings.isEnableRainbowSquigglyBrackets) annotateUtil(element, holder, "{", "}", NAME_SQUIGGLY_BRACKETS)
|
||||
if (settings.isEnableRainbowAngleBrackets) annotateUtil(element, holder, "<", ">", NAME_ANGLE_BRACKETS)
|
||||
} else {
|
||||
if (settings.isEnableRainbowRoundBrackets) annotateUtil(element, holder, "(", ")", NAME_ROUND_BRACKETS)
|
||||
if (settings.isEnableRainbowSquareBrackets) annotateUtil(element, holder, "[", "]", NAME_ROUND_BRACKETS)
|
||||
if (settings.isEnableRainbowSquigglyBrackets) annotateUtil(element, holder, "{", "}", NAME_ROUND_BRACKETS)
|
||||
if (settings.isEnableRainbowAngleBrackets) annotateUtil(element, holder, "<", ">", NAME_ROUND_BRACKETS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object RainbowUtils {
|
||||
|
||||
private val leftBracketsSet = setOf("(", "[", "{", "<")
|
||||
private val rightBracketsSet = setOf(")", "]", "}", ">")
|
||||
|
||||
val settings = RainbowSettings.instance
|
||||
|
||||
private tailrec fun iterateChildren(
|
||||
LEFT: String,
|
||||
RIGHT: String,
|
||||
currentNode: PsiElement,
|
||||
currentLevel: Int,
|
||||
currentChild: PsiElement
|
||||
): Int {
|
||||
val calculatedLevel = if (currentChild is LeafPsiElement) {
|
||||
//Using `currentChild.elementType.toString()` if we didn't want add more dependencies.
|
||||
if (!settings.cycleCountOnAllBrackets) {
|
||||
when (currentChild.text) {
|
||||
LEFT -> currentLevel + 1
|
||||
RIGHT -> currentLevel - 1
|
||||
else -> currentLevel
|
||||
}
|
||||
} else {
|
||||
when {
|
||||
leftBracketsSet.contains(currentChild.text) -> currentLevel + 1
|
||||
rightBracketsSet.contains(currentChild.text) -> currentLevel - 1
|
||||
else -> currentLevel
|
||||
}
|
||||
}
|
||||
} else currentLevel
|
||||
|
||||
return if ((currentChild != currentNode) && (currentChild != currentNode.parent.lastChild))
|
||||
iterateChildren(LEFT, RIGHT, currentNode, calculatedLevel, currentChild.nextSibling)
|
||||
else
|
||||
calculatedLevel
|
||||
}
|
||||
|
||||
private tailrec fun iterateParents(
|
||||
LEFT: String,
|
||||
RIGHT: String,
|
||||
currentNode: PsiElement,
|
||||
currentLevel: Int
|
||||
): Int = if (currentNode.parent !is PsiFile) {
|
||||
val calculatedLevel = iterateChildren(LEFT, RIGHT, currentNode, currentLevel, currentNode.parent.firstChild)
|
||||
iterateParents(LEFT, RIGHT, currentNode.parent, calculatedLevel)
|
||||
} else currentLevel
|
||||
|
||||
private fun getBracketLevel(element: LeafPsiElement, LEFT: String, RIGHT: String): Int {
|
||||
//Using `element.elementType.toString()` if we didn't want add more dependencies.
|
||||
val startLevel = if (element.text == RIGHT) 0 else -1
|
||||
return iterateParents(LEFT, RIGHT, element, startLevel)
|
||||
}
|
||||
|
||||
fun annotateUtil(element: LeafPsiElement, holder: AnnotationHolder,
|
||||
LEFT: String, RIGHT: String, rainbowName: String) {
|
||||
//Using `element.elementType.toString()` if we didn't want add more dependencies.
|
||||
val level = when (element.text) {
|
||||
LEFT, RIGHT -> getBracketLevel(element, LEFT, RIGHT)
|
||||
else -> -1
|
||||
}
|
||||
val scheme = EditorColorsManager.getInstance().globalScheme
|
||||
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
||||
if (level >= 1) {
|
||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||
.range(element.psi)
|
||||
.textAttributes(getRainbowColorByLevel(scheme, rainbowName, level))
|
||||
.create()
|
||||
}
|
||||
} else {
|
||||
if (level >= 0) {
|
||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||
.range(element.psi)
|
||||
.textAttributes(getRainbowColorByLevel(scheme, rainbowName, level))
|
||||
.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,108 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.color
|
||||
|
||||
import kotlin.math.floor
|
||||
|
||||
enum class Color(val hueRange: Pair<Int, Int>, val lowerBounds: List<Pair<Int, Int>>) {
|
||||
monochrome(
|
||||
Pair(-1, -1),
|
||||
listOf(Pair(0, 0), Pair(100, 0))
|
||||
),
|
||||
red(
|
||||
Pair(-26, 18),
|
||||
listOf(
|
||||
Pair(20, 100),
|
||||
Pair(30, 92),
|
||||
Pair(40, 89),
|
||||
Pair(50, 85),
|
||||
Pair(60, 78),
|
||||
Pair(70, 70),
|
||||
Pair(80, 60),
|
||||
Pair(90, 55),
|
||||
Pair(100, 50)
|
||||
)
|
||||
),
|
||||
orange(
|
||||
Pair(18, 46),
|
||||
listOf(Pair(20, 100), Pair(30, 93), Pair(40, 88), Pair(50, 86), Pair(60, 85), Pair(70, 70), Pair(100, 70))
|
||||
),
|
||||
yellow(
|
||||
Pair(46, 62),
|
||||
listOf(
|
||||
Pair(25, 100),
|
||||
Pair(40, 94),
|
||||
Pair(50, 89),
|
||||
Pair(60, 86),
|
||||
Pair(70, 84),
|
||||
Pair(80, 82),
|
||||
Pair(90, 80),
|
||||
Pair(100, 75)
|
||||
)
|
||||
),
|
||||
green(
|
||||
Pair(62, 178),
|
||||
listOf(
|
||||
Pair(30, 100),
|
||||
Pair(40, 90),
|
||||
Pair(50, 85),
|
||||
Pair(60, 81),
|
||||
Pair(70, 74),
|
||||
Pair(80, 64),
|
||||
Pair(90, 50),
|
||||
Pair(100, 40)
|
||||
)
|
||||
),
|
||||
blue(
|
||||
Pair(178, 257),
|
||||
listOf(
|
||||
Pair(20, 100),
|
||||
Pair(30, 86),
|
||||
Pair(40, 80),
|
||||
Pair(50, 74),
|
||||
Pair(60, 60),
|
||||
Pair(70, 52),
|
||||
Pair(80, 44),
|
||||
Pair(90, 39),
|
||||
Pair(100, 35)
|
||||
)
|
||||
),
|
||||
purple(
|
||||
Pair(257, 282),
|
||||
listOf(
|
||||
Pair(20, 100),
|
||||
Pair(30, 87),
|
||||
Pair(40, 79),
|
||||
Pair(50, 70),
|
||||
Pair(60, 65),
|
||||
Pair(70, 59),
|
||||
Pair(80, 52),
|
||||
Pair(90, 45),
|
||||
Pair(100, 42)
|
||||
)
|
||||
),
|
||||
pink(
|
||||
Pair(282, 334),
|
||||
listOf(Pair(20, 100), Pair(30, 90), Pair(40, 86), Pair(60, 84), Pair(80, 80), Pair(90, 75), Pair(100, 73))
|
||||
)
|
||||
}
|
||||
|
||||
fun Color.saturationRange(): Pair<Int, Int> {
|
||||
return Pair(lowerBounds.first().first, lowerBounds.last().first)
|
||||
}
|
||||
|
||||
fun Color.brightnessRange(saturation: Int): Pair<Int, Int> {
|
||||
for (i in 0 until lowerBounds.size - 1) {
|
||||
val s1 = lowerBounds[i].first.toFloat()
|
||||
val v1 = lowerBounds[i].second.toFloat()
|
||||
|
||||
val s2 = lowerBounds[i + 1].first.toFloat()
|
||||
val v2 = lowerBounds[i + 1].second.toFloat()
|
||||
|
||||
if (saturation.toFloat() in s1..s2) {
|
||||
val m = (v2 - v1) / (s2 - s1)
|
||||
val b = v1 - m * s1
|
||||
val minBrightness = m * saturation + b
|
||||
return Pair(floor(minBrightness).toInt(), 100)
|
||||
}
|
||||
}
|
||||
return Pair(0, 100)
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.color
|
||||
|
||||
|
||||
sealed class Hue
|
||||
object RandomHue : Hue()
|
||||
data class NumberHue(val value: Int) : Hue()
|
||||
data class ColorHue(val color: Color) : Hue()
|
||||
|
||||
fun Hue.getHueRange(): Pair<Int, Int> {
|
||||
return when (this) {
|
||||
is ColorHue -> color.hueRange
|
||||
is NumberHue -> if (value in 1..359) Pair(value, value) else Pair(0, 360)
|
||||
RandomHue -> Pair(0, 360)
|
||||
}
|
||||
}
|
||||
|
||||
fun fromString(str: String): Hue {
|
||||
return when {
|
||||
str == "random" -> RandomHue
|
||||
str.startsWith("#") -> NumberHue(Integer.parseInt(str.replaceFirst("#", ""), 16))
|
||||
else -> ColorHue(Color.valueOf(str))
|
||||
}
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.color
|
||||
|
||||
enum class Luminosity {
|
||||
random,
|
||||
bright,
|
||||
light,
|
||||
dark
|
||||
}
|
@@ -1,153 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.color
|
||||
|
||||
import kotlin.math.floor
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
/**
|
||||
* Generate a single random color with specified (or random) hue and luminosity.
|
||||
*/
|
||||
fun randomColor(
|
||||
hue: Hue = RandomHue,
|
||||
luminosity: Luminosity = Luminosity.random,
|
||||
): java.awt.Color {
|
||||
|
||||
// First we pick a hue (H)
|
||||
val hueValue = pickHue(hue)
|
||||
|
||||
// Then use H to determine saturation (S)
|
||||
val saturation = pickSaturation(hueValue, hue, luminosity)
|
||||
|
||||
// Then use S and H to determine brightness (B)
|
||||
val brightness = pickBrightness(hueValue, hue, saturation, luminosity)
|
||||
|
||||
return toColor(hueValue, saturation, brightness)
|
||||
}
|
||||
|
||||
private fun pickHue(hue: Hue): Int {
|
||||
val hueRange = hue.getHueRange()
|
||||
var hueValue = randomWithin(hueRange)
|
||||
// Instead of storing red as two separate ranges,
|
||||
// we group them, using negative numbers
|
||||
if (hueValue < 0) {
|
||||
hueValue += 360
|
||||
}
|
||||
return hueValue
|
||||
}
|
||||
|
||||
private fun pickSaturation(hueValue: Int, hue: Hue, luminosity: Luminosity): Int {
|
||||
if (hue == ColorHue(Color.monochrome)) {
|
||||
return 0
|
||||
}
|
||||
|
||||
val color: Color = matchColor(hueValue, hue)
|
||||
|
||||
val sMin = color.saturationRange().first
|
||||
val sMax = color.saturationRange().second
|
||||
|
||||
return when (luminosity) {
|
||||
Luminosity.random -> randomWithin(Pair(0, 100))
|
||||
Luminosity.bright -> randomWithin(Pair(55, sMax))
|
||||
Luminosity.light -> randomWithin(Pair(sMin, 55))
|
||||
Luminosity.dark -> randomWithin(Pair(sMax - 10, sMax))
|
||||
}
|
||||
}
|
||||
|
||||
private fun pickBrightness(hueValue: Int, hue: Hue, saturation: Int, luminosity: Luminosity): Int {
|
||||
val color: Color = matchColor(hueValue, hue)
|
||||
|
||||
val bMin = color.brightnessRange(saturation).first
|
||||
val bMax = color.brightnessRange(saturation).second
|
||||
|
||||
return when (luminosity) {
|
||||
Luminosity.random -> randomWithin(Pair(50, 100)) // I set this to 50 arbitrarily, they look more attractive
|
||||
Luminosity.bright -> randomWithin(Pair(bMin, bMax))
|
||||
Luminosity.light -> randomWithin(Pair((bMax + bMin) / 2, bMax))
|
||||
Luminosity.dark -> randomWithin(Pair(bMin, bMin + 20))
|
||||
}
|
||||
}
|
||||
|
||||
private fun toColor(hueValue: Int, saturation: Int, brightness: Int): java.awt.Color {
|
||||
val rgb = HSVtoRGB(hueValue, saturation, brightness)
|
||||
return java.awt.Color(rgb.first, rgb.second, rgb.third)
|
||||
}
|
||||
|
||||
|
||||
private fun HSVtoRGB(hueValue: Int, saturation: Int, brightness: Int): Triple<Int, Int, Int> {
|
||||
// This doesn't work for the values of 0 and 360
|
||||
// Here's the hacky fix
|
||||
// Rebase the h,s,v values
|
||||
val h: Float = hueValue.coerceIn(1, 359) / 360f
|
||||
val s = saturation / 100f
|
||||
val v = brightness / 100f
|
||||
|
||||
val hI = floor(h * 6f).toInt()
|
||||
val f = h * 6f - hI
|
||||
val p = v * (1f - s)
|
||||
val q = v * (1f - f * s)
|
||||
val t = v * (1f - (1f - f) * s)
|
||||
|
||||
var r = 256f
|
||||
var g = 256f
|
||||
var b = 256f
|
||||
|
||||
when (hI) {
|
||||
0 -> {
|
||||
r = v; g = t; b = p
|
||||
}
|
||||
1 -> {
|
||||
r = q; g = v; b = p
|
||||
}
|
||||
2 -> {
|
||||
r = p; g = v; b = t
|
||||
}
|
||||
3 -> {
|
||||
r = p; g = q; b = v
|
||||
}
|
||||
4 -> {
|
||||
r = t; g = p; b = v
|
||||
}
|
||||
5 -> {
|
||||
r = v; g = p; b = q
|
||||
}
|
||||
}
|
||||
|
||||
return Triple(floor(r * 255f).toInt(), floor(g * 255f).toInt(), floor(b * 255f).toInt())
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns hue into a color if it isn't already one.
|
||||
* First we check if hue was passed in as a color, and just return that if it is.
|
||||
* If not, we iterate through every color to see which one the given hueValue fits in.
|
||||
* For some reason if a matching hue is not found, just return Monochrome.
|
||||
*/
|
||||
private fun matchColor(hueValue: Int, hue: Hue): Color {
|
||||
return when (hue) {
|
||||
is ColorHue -> hue.color
|
||||
else -> {
|
||||
// Maps red colors to make picking hue easier
|
||||
var hueVal = hueValue
|
||||
if (hueVal in 334..360) {
|
||||
hueVal -= 360
|
||||
}
|
||||
|
||||
for (color in Color.values()) {
|
||||
if (hueVal in color.hueRange.first..color.hueRange.second) {
|
||||
return color
|
||||
}
|
||||
}
|
||||
// Returning Monochrome if we can't find a value, but this should never happen
|
||||
return Color.monochrome
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun randomWithin(range: Pair<Int, Int>): Int {
|
||||
// Generate random evenly distinct number from:
|
||||
// https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
||||
val goldenRatio = 0.618033988749895
|
||||
var r = Random.nextDouble()
|
||||
r += goldenRatio
|
||||
r %= 1
|
||||
return floor(range.first + r * (range.second + 1 - range.first)).toInt()
|
||||
}
|
@@ -1,263 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.indents
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.alphaBlend
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.endOffset
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.findNextSibling
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.findPrevSibling
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.lineNumber
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.startOffset
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.SoftWrap
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.editor.impl.EditorImpl
|
||||
import com.intellij.openapi.editor.impl.view.EditorPainter
|
||||
import com.intellij.openapi.editor.impl.view.VisualLinesIterator
|
||||
import com.intellij.openapi.editor.markup.CustomHighlighterRenderer
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import com.intellij.psi.xml.XmlTag
|
||||
import com.intellij.psi.xml.XmlToken
|
||||
import com.intellij.psi.xml.XmlTokenType
|
||||
import com.intellij.ui.paint.LinePainter2D
|
||||
import com.intellij.util.text.CharArrayUtil
|
||||
import java.awt.Graphics
|
||||
import java.awt.Graphics2D
|
||||
|
||||
/** From [com.intellij.codeInsight.daemon.impl.IndentGuideRenderer]
|
||||
* Commit history : https://sourcegraph.com/github.com/JetBrains/intellij-community/-/blob/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IndentGuideRenderer.java#tab=history
|
||||
* */
|
||||
class RainbowIndentGuideRenderer: CustomHighlighterRenderer {
|
||||
override fun paint(editor: Editor, highlighter: RangeHighlighter, g: Graphics) {
|
||||
if (editor !is EditorEx) return
|
||||
|
||||
val rainbowInfo = getRainbowInfo(editor, highlighter) ?: return
|
||||
|
||||
val startOffset = highlighter.startOffset
|
||||
val doc = highlighter.document
|
||||
if (startOffset >= doc.textLength) return
|
||||
|
||||
val endOffset = highlighter.endOffset
|
||||
|
||||
var off: Int
|
||||
var startLine = doc.getLineNumber(startOffset)
|
||||
|
||||
val chars = doc.charsSequence
|
||||
do {
|
||||
val start = doc.getLineStartOffset(startLine)
|
||||
val end = doc.getLineEndOffset(startLine)
|
||||
off = CharArrayUtil.shiftForward(chars, start, end, " \t")
|
||||
startLine--
|
||||
} while (startLine > 1 && off < doc.textLength && chars[off] == '\n')
|
||||
|
||||
val startPosition = editor.offsetToVisualPosition(off)
|
||||
val indentColumn = startPosition.column
|
||||
|
||||
if (indentColumn <= 0) return
|
||||
|
||||
val foldingModel = editor.foldingModel
|
||||
if (foldingModel.isOffsetCollapsed(off)) return
|
||||
|
||||
val headerRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(off)))
|
||||
val tailRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineStartOffset(doc.getLineNumber(endOffset)))
|
||||
|
||||
if (tailRegion != null && tailRegion === headerRegion) return
|
||||
|
||||
val guide = editor.indentsModel.caretIndentGuide
|
||||
val selected = if (guide != null) {
|
||||
val caretModel = editor.caretModel
|
||||
val caretOffset = caretModel.offset
|
||||
caretOffset in off until endOffset && caretModel.logicalPosition.column == indentColumn
|
||||
} else false
|
||||
|
||||
val lineHeight = editor.getLineHeight()
|
||||
val start = editor.visualPositionToXY(startPosition)
|
||||
start.y += lineHeight
|
||||
val endPosition = editor.offsetToVisualPosition(endOffset)
|
||||
val end = editor.visualPositionToXY(endPosition)
|
||||
var maxY = end.y
|
||||
if (endPosition.line == editor.offsetToVisualPosition(doc.textLength).line) {
|
||||
maxY += lineHeight
|
||||
}
|
||||
|
||||
val clip = g.clipBounds
|
||||
if (clip != null) {
|
||||
if (clip.y >= maxY || clip.y + clip.height <= start.y) {
|
||||
return
|
||||
}
|
||||
maxY = StrictMath.min(maxY, clip.y + clip.height)
|
||||
}
|
||||
if (start.y >= maxY) return
|
||||
val targetX = Math.max(0, start.x + EditorPainter.getIndentGuideShift(editor)).toDouble()
|
||||
g.color = if (selected) {
|
||||
rainbowInfo.color
|
||||
} else {
|
||||
val defaultBackground = editor.colorsScheme.defaultBackground
|
||||
rainbowInfo.color.alphaBlend(defaultBackground, 0.2f)
|
||||
}
|
||||
|
||||
// There is a possible case that indent line intersects soft wrap-introduced text. Example:
|
||||
// this is a long line <soft-wrap>
|
||||
// that| is soft-wrapped
|
||||
// |
|
||||
// | <- vertical indent
|
||||
//
|
||||
// Also it's possible that no additional intersections are added because of soft wrap:
|
||||
// this is a long line <soft-wrap>
|
||||
// | that is soft-wrapped
|
||||
// |
|
||||
// | <- vertical indent
|
||||
// We want to use the following approach then:
|
||||
// 1. Show only active indent if it crosses soft wrap-introduced text;
|
||||
// 2. Show indent as is if it doesn't intersect with soft wrap-introduced text;
|
||||
val softWraps = editor.softWrapModel.registeredSoftWraps
|
||||
if (selected || softWraps.isEmpty()) {
|
||||
LinePainter2D.paint(g as Graphics2D, targetX, start.y.toDouble(), targetX, maxY - 1.toDouble())
|
||||
} else {
|
||||
var startY = start.y
|
||||
var startVisualLine = startPosition.line + 1
|
||||
if (clip != null && startY < clip.y) {
|
||||
startY = clip.y
|
||||
startVisualLine = editor.yToVisualLine(clip.y)
|
||||
}
|
||||
val it = VisualLinesIterator(editor as EditorImpl, startVisualLine)
|
||||
while (!it.atEnd()) {
|
||||
val currY: Int = it.y
|
||||
if (currY >= startY) {
|
||||
if (currY >= maxY) break
|
||||
if (it.startsWithSoftWrap()) {
|
||||
val softWrap: SoftWrap = softWraps[it.startOrPrevWrapIndex]
|
||||
if (softWrap.indentInColumns < indentColumn) {
|
||||
if (startY < currY) {
|
||||
LinePainter2D.paint((g as Graphics2D), targetX, startY.toDouble(), targetX, currY - 1.toDouble())
|
||||
}
|
||||
startY = currY + lineHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
it.advance()
|
||||
}
|
||||
if (startY < maxY) {
|
||||
LinePainter2D.paint((g as Graphics2D), targetX, startY.toDouble(), targetX, maxY - 1.toDouble())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val XML_TAG_PARENT_CONDITION = Condition<PsiElement> { it is XmlTag }
|
||||
private val XML_END_TAG_START_CONDITION: (PsiElement) -> Boolean = { element ->
|
||||
element is XmlToken && element.tokenType == XmlTokenType.XML_END_TAG_START
|
||||
}
|
||||
private val XML_TAG_END_CONDITION: (PsiElement) -> Boolean = { element ->
|
||||
element is XmlToken && element.tokenType == XmlTokenType.XML_TAG_END
|
||||
}
|
||||
|
||||
private fun getRainbowInfo(editor: EditorEx, highlighter: RangeHighlighter): RainbowInfo? {
|
||||
val virtualFile = editor.virtualFile?.takeIf { it.isValid } ?: return null
|
||||
val document = editor.document
|
||||
val project = editor.project ?: return null
|
||||
val psiFile = PsiManager.getInstance(project).findFile(virtualFile) ?: return null
|
||||
var element = try {
|
||||
psiFile.findElementAt(highlighter.endOffset)?.parent ?: return null
|
||||
} catch (e: Throwable) {
|
||||
return null
|
||||
}
|
||||
|
||||
var rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element]
|
||||
if (rainbowInfo == null && psiFile is XmlFile && element !is XmlTag) {
|
||||
element = PsiTreeUtil.findFirstParent(element, true, XML_TAG_PARENT_CONDITION) ?: return null
|
||||
rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element] ?: return null
|
||||
}
|
||||
|
||||
if (!element.isValid || !checkBoundary(document, element, highlighter)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return rainbowInfo
|
||||
}
|
||||
|
||||
/***
|
||||
* introduced from https://github.com/izhangzhihao/intellij-rainbow-brackets/commit/d9d40e6910e9c15fbdcba12280df18019ea170b5
|
||||
*/
|
||||
private fun checkBoundary(document: Document, element: PsiElement, highlighter: RangeHighlighter): Boolean {
|
||||
val elementStartLine = document.lineNumber(element.startOffset) ?: return false
|
||||
val highlighterStartLine = document.lineNumber(highlighter.startOffset) ?: return false
|
||||
|
||||
var xmlStartTagEndLine: Int? = null
|
||||
var xmlEndTagStartLine: Int? = null
|
||||
|
||||
val isValidStartBoundary = if (element is XmlTag) {
|
||||
/*
|
||||
* <tag // [*] element & highlighter start line
|
||||
* | <- vertical indent
|
||||
* > // [*] highlighter start/end line, start tag end line
|
||||
* | <- vertical indent
|
||||
* </tag // [*] highlighter start/end line, end tag start line
|
||||
* | <- vertical indent
|
||||
* > // [ ] element/highlighter end line
|
||||
*/
|
||||
xmlStartTagEndLine = element.getStartTagEndLineNumber(document)
|
||||
xmlEndTagStartLine = element.getEndTagStartLineNumber(document)
|
||||
|
||||
highlighterStartLine == elementStartLine ||
|
||||
highlighterStartLine == xmlStartTagEndLine ||
|
||||
highlighterStartLine == xmlEndTagStartLine
|
||||
} else {
|
||||
/*
|
||||
* Element start line > Highlighter start line:
|
||||
* function foo(arg1, // highlighter start line
|
||||
* | arg2) { // element start line
|
||||
* | <- vertical indent
|
||||
* } // element & highlighter end line
|
||||
*/
|
||||
elementStartLine >= highlighterStartLine
|
||||
}
|
||||
if (!isValidStartBoundary) {
|
||||
return false
|
||||
}
|
||||
|
||||
val elementEndLine = document.lineNumber(element.endOffset) ?: return false
|
||||
val highlighterEndLine = document.lineNumber(highlighter.endOffset) ?: return false
|
||||
val isValidEndBoundary = if (element is XmlTag) {
|
||||
/*
|
||||
* <tag // [ ] element & highlighter start line
|
||||
* | <- vertical indent
|
||||
* > // [*] highlighter start/end line, start tag end line
|
||||
* | <- vertical indent
|
||||
* </tag // [*] highlighter start/end line, end tag start line
|
||||
* | <- vertical indent
|
||||
* > // [*] element/highlighter end line
|
||||
*/
|
||||
highlighterEndLine == elementEndLine ||
|
||||
highlighterEndLine == xmlStartTagEndLine ||
|
||||
highlighterEndLine == xmlEndTagStartLine
|
||||
} else {
|
||||
/*
|
||||
* Element end line != Highlighter end line:
|
||||
* function foo() { // element & highlighter start line
|
||||
* | <- vertical indent
|
||||
* var bar = "bar"; // highlighter end line
|
||||
* } // element end line
|
||||
*/
|
||||
elementEndLine == highlighterEndLine
|
||||
}
|
||||
if (!isValidEndBoundary) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun XmlTag.getStartTagEndLineNumber(document: Document): Int? =
|
||||
firstChild?.findNextSibling(XML_TAG_END_CONDITION)?.let { document.lineNumber(it.startOffset) }
|
||||
|
||||
private fun XmlTag.getEndTagStartLineNumber(document: Document): Int? =
|
||||
lastChild?.findPrevSibling(XML_END_TAG_START_CONDITION)?.let { document.lineNumber(it.startOffset) }
|
||||
|
||||
}
|
||||
}
|
@@ -1,365 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.indents
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPass
|
||||
import com.intellij.codeInsight.highlighting.BraceMatchingUtil
|
||||
import com.intellij.codeInsight.highlighting.CodeBlockSupportHandler
|
||||
import com.intellij.ide.actions.ToggleZenModeAction
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.LanguageParserDefinitions
|
||||
import com.intellij.openapi.editor.Editor
|
||||
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.markup.HighlighterTargetArea
|
||||
import com.intellij.openapi.editor.markup.MarkupModel
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.Segment
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import com.intellij.util.DocumentUtil
|
||||
import com.intellij.util.containers.IntStack
|
||||
import com.intellij.util.text.CharArrayUtil
|
||||
import java.lang.StrictMath.abs
|
||||
import java.lang.StrictMath.min
|
||||
import java.util.Collections
|
||||
|
||||
/** From [com.intellij.codeInsight.daemon.impl.IndentsPass]
|
||||
* Commit history: https://sourcegraph.com/github.com/JetBrains/intellij-community/-/blob/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IndentsPass.java#tab=history
|
||||
* mirror changes start from `Make it possible to ignore indent guides more granularly and do so for C#`
|
||||
* */
|
||||
class RainbowIndentsPass internal constructor(
|
||||
project: Project,
|
||||
editor: Editor,
|
||||
private val myFile: PsiFile
|
||||
) : TextEditorHighlightingPass(project, editor.document, false), DumbAware {
|
||||
|
||||
private val myEditor: EditorEx = editor as EditorEx
|
||||
|
||||
@Volatile
|
||||
private var myRanges = emptyList<TextRange>()
|
||||
|
||||
@Volatile
|
||||
private var myDescriptors = emptyList<IndentGuideDescriptor>()
|
||||
|
||||
override fun doCollectInformation(progress: ProgressIndicator) {
|
||||
val stamp = myEditor.getUserData(LAST_TIME_INDENTS_BUILT)
|
||||
if (stamp != null && stamp.toLong() == nowStamp()) return
|
||||
|
||||
myDescriptors = buildDescriptors()
|
||||
|
||||
val ranges = ArrayList<TextRange>()
|
||||
for (descriptor in myDescriptors) {
|
||||
ProgressManager.checkCanceled()
|
||||
val endOffset = if (descriptor.endLine < document.lineCount) {
|
||||
document.getLineStartOffset(descriptor.endLine)
|
||||
} else {
|
||||
document.textLength
|
||||
}
|
||||
ranges.add(TextRange(document.getLineStartOffset(descriptor.startLine), endOffset))
|
||||
}
|
||||
|
||||
Collections.sort(ranges, Segment.BY_START_OFFSET_THEN_END_OFFSET)
|
||||
myRanges = ranges
|
||||
}
|
||||
|
||||
private fun nowStamp(): Long = if (isRainbowIndentGuidesShown(this.myProject)) document.modificationStamp xor (EditorUtil.getTabSize(myEditor).toLong() shl 24) else -1
|
||||
|
||||
override fun doApplyInformationToEditor() {
|
||||
val stamp = myEditor.getUserData(LAST_TIME_INDENTS_BUILT)
|
||||
val nowStamp = nowStamp()
|
||||
|
||||
if (stamp == nowStamp) return
|
||||
|
||||
myEditor.putUserData(LAST_TIME_INDENTS_BUILT, nowStamp)
|
||||
|
||||
val oldHighlighters = myEditor.getUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY)
|
||||
if (nowStamp == -1L) {
|
||||
if (oldHighlighters != null) {
|
||||
for (oldHighlighter in oldHighlighters) {
|
||||
oldHighlighter.dispose()
|
||||
}
|
||||
oldHighlighters.clear()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val newHighlighters = ArrayList<RangeHighlighter>()
|
||||
val mm = myEditor.markupModel
|
||||
var curRange = 0
|
||||
|
||||
if (oldHighlighters != null) {
|
||||
// after document change some range highlighters could have become invalid, or the order could have been broken
|
||||
oldHighlighters.sortWith(Comparator.comparing { h: RangeHighlighter -> !h.isValid }
|
||||
.thenComparing(Segment.BY_START_OFFSET_THEN_END_OFFSET))
|
||||
|
||||
var curHighlight = 0
|
||||
while (curRange < myRanges.size && curHighlight < oldHighlighters.size) {
|
||||
val range = myRanges[curRange]
|
||||
val highlighter = oldHighlighters[curHighlight]
|
||||
if (!highlighter.isValid) break
|
||||
|
||||
val cmp = compare(range, highlighter)
|
||||
when {
|
||||
cmp < 0 -> {
|
||||
newHighlighters.add(createHighlighter(mm, range))
|
||||
curRange++
|
||||
}
|
||||
cmp > 0 -> {
|
||||
highlighter.dispose()
|
||||
curHighlight++
|
||||
}
|
||||
else -> {
|
||||
newHighlighters.add(highlighter)
|
||||
curHighlight++
|
||||
curRange++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (curHighlight < oldHighlighters.size) {
|
||||
val highlighter = oldHighlighters[curHighlight]
|
||||
if (!highlighter.isValid) break
|
||||
highlighter.dispose()
|
||||
curHighlight++
|
||||
}
|
||||
}
|
||||
|
||||
val startRangeIndex = curRange
|
||||
DocumentUtil.executeInBulk(document, myRanges.size > 10000) {
|
||||
for (i in startRangeIndex until myRanges.size) {
|
||||
newHighlighters.add(createHighlighter(mm, myRanges[i]))
|
||||
}
|
||||
}
|
||||
|
||||
myEditor.putUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY, newHighlighters)
|
||||
myEditor.indentsModel.assumeIndents(myDescriptors)
|
||||
}
|
||||
|
||||
private fun buildDescriptors(): List<IndentGuideDescriptor> {
|
||||
if (!isRainbowIndentGuidesShown(this.myProject)) return emptyList()
|
||||
|
||||
val calculator = IndentsCalculator()
|
||||
calculator.calculate()
|
||||
val lineIndents = calculator.lineIndents
|
||||
|
||||
val lines = IntStack()
|
||||
val indents = IntStack()
|
||||
|
||||
lines.push(0)
|
||||
indents.push(0)
|
||||
val descriptors = ArrayList<IndentGuideDescriptor>()
|
||||
for (line in 1 until lineIndents.size) {
|
||||
ProgressManager.checkCanceled()
|
||||
val curIndent = abs(lineIndents[line])
|
||||
|
||||
while (!indents.empty() && curIndent <= indents.peek()) {
|
||||
ProgressManager.checkCanceled()
|
||||
val level = indents.pop()
|
||||
val startLine = lines.pop()
|
||||
if (level > 0) {
|
||||
for (i in startLine until line) {
|
||||
if (level != abs(lineIndents[i])) {
|
||||
descriptors.add(createDescriptor(level, startLine, line, lineIndents))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val prevLine = line - 1
|
||||
val prevIndent = abs(lineIndents[prevLine])
|
||||
|
||||
if (curIndent - prevIndent > 1) {
|
||||
lines.push(prevLine)
|
||||
indents.push(prevIndent)
|
||||
}
|
||||
}
|
||||
|
||||
while (!indents.empty()) {
|
||||
ProgressManager.checkCanceled()
|
||||
val level = indents.pop()
|
||||
val startLine = lines.pop()
|
||||
if (level > 0) {
|
||||
descriptors.add(createDescriptor(level, startLine, document.lineCount, lineIndents))
|
||||
}
|
||||
}
|
||||
return descriptors
|
||||
}
|
||||
|
||||
private fun createDescriptor(
|
||||
level: Int,
|
||||
startLine: Int,
|
||||
endLine: Int,
|
||||
lineIndents: IntArray
|
||||
): IndentGuideDescriptor {
|
||||
var sLine = startLine
|
||||
while (sLine > 0 && lineIndents[sLine] < 0) sLine--
|
||||
// int codeConstructStartLine = findCodeConstructStartLine(startLine);
|
||||
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() {
|
||||
val myComments: MutableMap<Language, TokenSet> = HashMap()
|
||||
val lineIndents: IntArray // negative value means the line is empty (or contains a comment) and indent
|
||||
|
||||
// (denoted by absolute value) was deduced from enclosing non-empty lines
|
||||
val myChars: CharSequence
|
||||
|
||||
init {
|
||||
lineIndents = IntArray(document.lineCount)
|
||||
myChars = document.charsSequence
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates line indents for the [target document][.myDocument].
|
||||
*/
|
||||
fun calculate() {
|
||||
val fileType = myFile.fileType
|
||||
val tabSize = EditorUtil.getTabSize(myEditor)
|
||||
|
||||
for (line in lineIndents.indices) {
|
||||
ProgressManager.checkCanceled()
|
||||
val lineStart = document.getLineStartOffset(line)
|
||||
val lineEnd = document.getLineEndOffset(line)
|
||||
var offset = lineStart
|
||||
var column = 0
|
||||
outer@ while (offset < lineEnd) {
|
||||
when (myChars[offset]) {
|
||||
' ' -> column++
|
||||
'\t' -> column = (column / tabSize + 1) * tabSize
|
||||
else -> break@outer
|
||||
}
|
||||
offset++
|
||||
}
|
||||
// treating commented lines in the same way as empty lines
|
||||
// Blank line marker
|
||||
lineIndents[line] = if (offset == lineEnd || isComment(offset)) -1 else column
|
||||
}
|
||||
|
||||
var topIndent = 0
|
||||
var line = 0
|
||||
while (line < lineIndents.size) {
|
||||
ProgressManager.checkCanceled()
|
||||
if (lineIndents[line] >= 0) {
|
||||
topIndent = lineIndents[line]
|
||||
} else {
|
||||
val startLine = line
|
||||
while (line < lineIndents.size && lineIndents[line] < 0) {
|
||||
line++
|
||||
}
|
||||
|
||||
val bottomIndent = if (line < lineIndents.size) lineIndents[line] else topIndent
|
||||
|
||||
var indent = min(topIndent, bottomIndent)
|
||||
if (bottomIndent < topIndent) {
|
||||
val lineStart = document.getLineStartOffset(line)
|
||||
val lineEnd = document.getLineEndOffset(line)
|
||||
val nonWhitespaceOffset = CharArrayUtil.shiftForward(myChars, lineStart, lineEnd, " \t")
|
||||
val iterator = myEditor.highlighter.createIterator(nonWhitespaceOffset)
|
||||
val tokenType = iterator.tokenType
|
||||
if (BraceMatchingUtil.isRBraceToken(iterator, myChars, fileType) ||
|
||||
tokenType != null &&
|
||||
CodeBlockSupportHandler.findMarkersRanges(myFile, tokenType.language, nonWhitespaceOffset).isNotEmpty()) {
|
||||
indent = topIndent
|
||||
}
|
||||
}
|
||||
|
||||
for (blankLine in startLine until line) {
|
||||
assert(lineIndents[blankLine] == -1)
|
||||
lineIndents[blankLine] = -min(topIndent, indent)
|
||||
}
|
||||
|
||||
|
||||
line-- // will be incremented back at the end of the loop;
|
||||
}
|
||||
line++
|
||||
}
|
||||
}
|
||||
|
||||
private fun isComment(offset: Int): Boolean {
|
||||
val it = myEditor.highlighter.createIterator(offset)
|
||||
val tokenType = try {
|
||||
it.tokenType
|
||||
} catch (e: Throwable) {
|
||||
return false
|
||||
}
|
||||
val language = tokenType.language
|
||||
var comments: TokenSet? = myComments[language]
|
||||
if (comments == null) {
|
||||
val definition = LanguageParserDefinitions.INSTANCE.forLanguage(language)
|
||||
if (definition != null) {
|
||||
comments = definition.commentTokens
|
||||
}
|
||||
if (comments == null) {
|
||||
return false
|
||||
} else {
|
||||
myComments[language] = comments
|
||||
}
|
||||
}
|
||||
return comments.contains(tokenType)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val INDENT_HIGHLIGHTERS_IN_EDITOR_KEY = Key.create<MutableList<RangeHighlighter>>("_INDENT_HIGHLIGHTERS_IN_EDITOR_KEY_")
|
||||
private val LAST_TIME_INDENTS_BUILT = Key.create<Long>("_LAST_TIME_INDENTS_BUILT_")
|
||||
|
||||
private val RENDERER = RainbowIndentGuideRenderer()
|
||||
|
||||
private fun isRainbowIndentGuidesShown(project: Project): Boolean {
|
||||
if (RainbowSettings.instance.disableRainbowIndentsInZenMode && isZenModeEnabled(project)) {
|
||||
return false
|
||||
}
|
||||
return RainbowSettings.instance.isRainbowEnabled && RainbowSettings.instance.isShowRainbowIndentGuides
|
||||
}
|
||||
|
||||
private fun isZenModeEnabled(project: Project) =
|
||||
ToggleZenModeAction.isZenModeEnabled(project)
|
||||
|
||||
private fun createHighlighter(mm: MarkupModel, range: TextRange): RangeHighlighter {
|
||||
return mm.addRangeHighlighter(
|
||||
range.startOffset,
|
||||
range.endOffset,
|
||||
0,
|
||||
null,
|
||||
HighlighterTargetArea.EXACT_RANGE
|
||||
).apply {
|
||||
customRenderer = RENDERER
|
||||
}
|
||||
}
|
||||
|
||||
private fun compare(r: TextRange, h: RangeHighlighter): Int {
|
||||
val answer = r.startOffset - h.startOffset
|
||||
return if (answer != 0) answer else r.endOffset - h.endOffset
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.indents
|
||||
|
||||
import com.intellij.codeHighlighting.Pass
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPass
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactoryRegistrar
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
|
||||
class RainbowIndentsPassFactory :
|
||||
TextEditorHighlightingPassFactoryRegistrar, TextEditorHighlightingPassFactory {
|
||||
|
||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass {
|
||||
return RainbowIndentsPass(file.project, editor, file)
|
||||
}
|
||||
|
||||
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
||||
registrar.registerTextEditorHighlightingPass(
|
||||
this,
|
||||
TextEditorHighlightingPassRegistrar.Anchor.LAST,
|
||||
Pass.LAST_PASS,
|
||||
false,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.listener
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
||||
import com.intellij.openapi.editor.colors.EditorColorsListener
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
|
||||
class RainbowColorsSchemeListener : EditorColorsListener {
|
||||
|
||||
override fun globalSchemeChange(scheme: EditorColorsScheme?) {
|
||||
scheme?.let { RainbowHighlighter.fixHighlighting(it) }
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.provider
|
||||
|
||||
import com.intellij.lang.BracePair
|
||||
import com.jetbrains.php.lang.lexer.PhpTokenTypes
|
||||
|
||||
// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/423
|
||||
class PHPBracePairProvider : BracePairProvider {
|
||||
override fun blackList(): List<BracePair> = listOf(
|
||||
BracePair(PhpTokenTypes.PHP_OPENING_TAG, PhpTokenTypes.PHP_CLOSING_TAG, false),
|
||||
BracePair(PhpTokenTypes.PHP_ECHO_OPENING_TAG, PhpTokenTypes.PHP_CLOSING_TAG, false)
|
||||
)
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.provider
|
||||
|
||||
import com.intellij.lang.BracePair
|
||||
import com.intellij.sh.ShTypes
|
||||
|
||||
class SHBracePairProvider : BracePairProvider {
|
||||
override fun blackList(): List<BracePair> = listOf(
|
||||
BracePair(ShTypes.HEREDOC_MARKER_START, ShTypes.HEREDOC_MARKER_END, false),
|
||||
BracePair(ShTypes.DO, ShTypes.DONE, true),
|
||||
BracePair(ShTypes.IF, ShTypes.FI, true),
|
||||
BracePair(ShTypes.CASE, ShTypes.ESAC, true)
|
||||
)
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.settings
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.form.RainbowOptionsPanel
|
||||
import com.intellij.application.options.colors.ColorAndFontOptions
|
||||
import com.intellij.application.options.colors.ColorAndFontPanelFactory
|
||||
import com.intellij.application.options.colors.ColorAndFontSettingsListener
|
||||
import com.intellij.application.options.colors.NewColorAndFontPanel
|
||||
import com.intellij.application.options.colors.PreviewPanel
|
||||
import com.intellij.application.options.colors.SchemesPanel
|
||||
import com.intellij.openapi.options.colors.AttributesDescriptor
|
||||
import com.intellij.openapi.options.colors.ColorAndFontDescriptorsProvider
|
||||
import com.intellij.openapi.options.colors.ColorDescriptor
|
||||
import com.intellij.psi.codeStyle.DisplayPriority
|
||||
import com.intellij.psi.codeStyle.DisplayPrioritySortable
|
||||
|
||||
|
||||
class RainbowColorsPageFactory : ColorAndFontPanelFactory, ColorAndFontDescriptorsProvider, DisplayPrioritySortable {
|
||||
|
||||
override fun getDisplayName(): String = RAINBOW_BRACKETS_GROUP
|
||||
|
||||
override fun getPanelDisplayName(): String = RAINBOW_BRACKETS_GROUP
|
||||
|
||||
override fun getPriority(): DisplayPriority = DisplayPriority.COMMON_SETTINGS
|
||||
|
||||
override fun createPanel(options: ColorAndFontOptions): NewColorAndFontPanel {
|
||||
val emptyPreview = PreviewPanel.Empty()
|
||||
val schemesPanel = SchemesPanel(options)
|
||||
val optionsPanel = RainbowOptionsPanel(options, schemesPanel, RAINBOW_BRACKETS_GROUP)
|
||||
|
||||
schemesPanel.addListener(object : ColorAndFontSettingsListener.Abstract() {
|
||||
override fun schemeChanged(source: Any) {
|
||||
optionsPanel.updateOptionsList()
|
||||
}
|
||||
})
|
||||
|
||||
return NewColorAndFontPanel(schemesPanel, optionsPanel, emptyPreview, RAINBOW_BRACKETS_GROUP, null, null)
|
||||
}
|
||||
|
||||
override fun getAttributeDescriptors(): Array<AttributesDescriptor> = ATTRIBUTE_DESCRIPTORS
|
||||
|
||||
override fun getColorDescriptors(): Array<ColorDescriptor> = emptyArray()
|
||||
|
||||
companion object {
|
||||
private const val RAINBOW_BRACKETS_GROUP = "Rainbow Brackets"
|
||||
private val ATTRIBUTE_DESCRIPTORS: Array<AttributesDescriptor> by lazy {
|
||||
createDescriptors(RainbowHighlighter.NAME_ROUND_BRACKETS) +
|
||||
createDescriptors(RainbowHighlighter.NAME_SQUARE_BRACKETS) +
|
||||
createDescriptors(RainbowHighlighter.NAME_SQUIGGLY_BRACKETS) +
|
||||
createDescriptors(RainbowHighlighter.NAME_ANGLE_BRACKETS)
|
||||
}
|
||||
|
||||
private fun createDescriptors(name: String): Array<AttributesDescriptor> {
|
||||
return RainbowHighlighter.getRainbowAttributesKeys(name)
|
||||
.map { key -> AttributesDescriptor("$name:$key", key) }
|
||||
.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.settings
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.form.RainbowSettingsForm
|
||||
import com.intellij.openapi.options.ConfigurationException
|
||||
import com.intellij.openapi.options.SearchableConfigurable
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.JComponent
|
||||
|
||||
class RainbowConfigurable : SearchableConfigurable {
|
||||
private var settingsForm: RainbowSettingsForm? = null
|
||||
|
||||
override fun createComponent(): JComponent? {
|
||||
settingsForm = settingsForm ?: RainbowSettingsForm()
|
||||
return settingsForm?.component()
|
||||
}
|
||||
|
||||
override fun isModified(): Boolean {
|
||||
return settingsForm?.isModified ?: return false
|
||||
}
|
||||
|
||||
@Throws(ConfigurationException::class)
|
||||
override fun apply() {
|
||||
val settings = RainbowSettings.instance
|
||||
settings.isRainbowEnabled = settingsForm?.isRainbowEnabled() ?: true
|
||||
settings.isEnableRainbowRoundBrackets = settingsForm?.isRainbowRoundBracketsEnabled() ?: true
|
||||
settings.isEnableRainbowAngleBrackets = settingsForm?.isRainbowAngleBracketsEnabled() ?: true
|
||||
settings.isEnableRainbowSquigglyBrackets = settingsForm?.isRainbowSquigglyBracketsEnabled() ?: true
|
||||
settings.isEnableRainbowSquareBrackets = settingsForm?.isRainbowSquareBracketsEnabled() ?: true
|
||||
settings.isShowRainbowIndentGuides = settingsForm?.isShowRainbowIndentGuides() ?: false
|
||||
settings.isDoNOTRainbowifyBracketsWithoutContent = settingsForm?.isDoNOTRainbowifyBracketsWithoutContent()
|
||||
?: false
|
||||
settings.isDoNOTRainbowifyTheFirstLevel = settingsForm?.isDoNOTRainbowifyTheFirstLevel() ?: false
|
||||
settings.pressAnyKeyToRemoveTheHighlightingEffects = settingsForm?.pressAnyKeyToRemoveTheHighlightingEffects()
|
||||
?: false
|
||||
settings.applyColorsOfRoundForAllBrackets = settingsForm?.applyColorsOfRoundForAllBrackets()
|
||||
?: false
|
||||
settings.cycleCountOnAllBrackets = settingsForm?.cycleCountOnAllBrackets()
|
||||
?: false
|
||||
settings.numberOfColors = settingsForm?.numberOfColors() ?: 5
|
||||
settings.languageBlacklist = settingsForm?.languageBlacklist() ?: emptySet()
|
||||
settings.disableRainbowIndentsInZenMode = settingsForm?.disableRainbowIndentsInZenMode() ?: true
|
||||
settings.useColorGenerator = settingsForm?.useColorGenerator() ?: false
|
||||
settings.rainbowifyTagNameInXML = settingsForm?.rainbowifyTagNameInXML() ?: false
|
||||
settings.doNOTRainbowifyTemplateString = settingsForm?.doNOTRainbowifyTemplateString() ?: false
|
||||
settings.doNOTRainbowifyBigFiles = settingsForm?.doNOTRainbowifyBigFiles() ?: true
|
||||
settings.bigFilesLinesThreshold = settingsForm?.bigFilesLinesThreshold() ?: 1000
|
||||
settings.rainbowifyPythonKeywords = settingsForm?.rainbowifyPythonKeywords() ?: false
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
settingsForm?.loadSettings()
|
||||
}
|
||||
|
||||
override fun disposeUIResources() {
|
||||
settingsForm = null
|
||||
}
|
||||
|
||||
@Nls
|
||||
override fun getDisplayName() = "Rainbow Brackets"
|
||||
|
||||
override fun getId(): String = ID
|
||||
|
||||
companion object {
|
||||
val ID = "preferences.rainbow.brackets"
|
||||
}
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.settings
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil.copyBean
|
||||
import org.jetbrains.annotations.Nullable
|
||||
|
||||
|
||||
@State(name = "RainbowSettings", storages = [(Storage("rainbow_brackets.xml"))])
|
||||
class RainbowSettings : PersistentStateComponent<RainbowSettings> {
|
||||
/**
|
||||
* default value
|
||||
*/
|
||||
var isRainbowEnabled = true
|
||||
var isEnableRainbowRoundBrackets = true
|
||||
var isEnableRainbowSquigglyBrackets = true
|
||||
var isEnableRainbowSquareBrackets = true
|
||||
var isEnableRainbowAngleBrackets = true
|
||||
var isShowRainbowIndentGuides = true
|
||||
var isDoNOTRainbowifyBracketsWithoutContent = false
|
||||
var isDoNOTRainbowifyTheFirstLevel = false
|
||||
var isRainbowifyHTMLInsideJS = true
|
||||
var isRainbowifyKotlinLabel = true
|
||||
var isRainbowifyKotlinFunctionLiteralBracesAndArrow = true
|
||||
var isOverrideMatchedBraceAttributes = true
|
||||
var pressAnyKeyToRemoveTheHighlightingEffects = false
|
||||
var applyColorsOfRoundForAllBrackets = false
|
||||
|
||||
//https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/391
|
||||
var cycleCountOnAllBrackets = false
|
||||
var numberOfColors = 5
|
||||
|
||||
var disableRainbowIndentsInZenMode = true
|
||||
var useColorGenerator = false
|
||||
var customColorGeneratorOption: String? = null
|
||||
var rainbowifyTagNameInXML = false
|
||||
var doNOTRainbowifyTemplateString = false
|
||||
var doNOTRainbowifyBigFiles = true
|
||||
var bigFilesLinesThreshold = 1000
|
||||
|
||||
var languageBlacklist: Set<String> = setOf("hocon", "mxml")
|
||||
|
||||
var suppressDisabledCheck = false
|
||||
var suppressBigFileCheck = false
|
||||
var suppressBlackListCheck = false
|
||||
var rainbowifyPythonKeywords = false
|
||||
|
||||
@Nullable
|
||||
override fun getState() = this
|
||||
|
||||
override fun loadState(state: RainbowSettings) {
|
||||
copyBean(state, this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val instance: RainbowSettings
|
||||
get() = ApplicationManager.getApplication().getService(RainbowSettings::class.java)
|
||||
}
|
||||
}
|
@@ -1,266 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.settings.form
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.application.options.colors.ColorAndFontOptions
|
||||
import com.intellij.application.options.colors.ColorAndFontSettingsListener
|
||||
import com.intellij.application.options.colors.OptionsPanel
|
||||
import com.intellij.application.options.colors.SchemesPanel
|
||||
import com.intellij.application.options.colors.TextAttributesDescription
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.ui.ColorPanel
|
||||
import com.intellij.ui.components.JBCheckBox
|
||||
import com.intellij.ui.treeStructure.Tree
|
||||
import com.intellij.util.EventDispatcher
|
||||
import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode
|
||||
import java.awt.Color
|
||||
import java.awt.event.ActionListener
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
import javax.swing.tree.DefaultMutableTreeNode
|
||||
import javax.swing.tree.DefaultTreeModel
|
||||
import javax.swing.tree.TreePath
|
||||
import javax.swing.tree.TreeSelectionModel
|
||||
|
||||
|
||||
class RainbowOptionsPanel(
|
||||
private val options: ColorAndFontOptions,
|
||||
private val schemesProvider: SchemesPanel,
|
||||
private val category: String
|
||||
) : OptionsPanel {
|
||||
|
||||
private lateinit var rootPanel: JPanel
|
||||
private lateinit var optionsTree: Tree
|
||||
|
||||
private lateinit var rainbow: JBCheckBox
|
||||
|
||||
private lateinit var colorLabel1: JLabel
|
||||
private lateinit var colorLabel2: JLabel
|
||||
private lateinit var colorLabel3: JLabel
|
||||
private lateinit var colorLabel4: JLabel
|
||||
private lateinit var colorLabel5: JLabel
|
||||
|
||||
private val colorLabels: Array<JLabel>
|
||||
|
||||
private lateinit var color1: ColorPanel
|
||||
private lateinit var color2: ColorPanel
|
||||
private lateinit var color3: ColorPanel
|
||||
private lateinit var color4: ColorPanel
|
||||
private lateinit var color5: ColorPanel
|
||||
|
||||
private val colors: Array<ColorPanel>
|
||||
|
||||
private lateinit var gradientLabel: JLabel
|
||||
|
||||
private val properties: PropertiesComponent = PropertiesComponent.getInstance()
|
||||
private val eventDispatcher: EventDispatcher<ColorAndFontSettingsListener> =
|
||||
EventDispatcher.create(ColorAndFontSettingsListener::class.java)
|
||||
|
||||
init {
|
||||
colors = arrayOf(color1, color2, color3, color4, color5)
|
||||
colorLabels = arrayOf(colorLabel1, colorLabel2, colorLabel3, colorLabel4, colorLabel5)
|
||||
|
||||
val actionListener = ActionListener {
|
||||
eventDispatcher.multicaster.settingsChanged()
|
||||
options.stateChanged()
|
||||
}
|
||||
rainbow.addActionListener(actionListener)
|
||||
for (c in colors) {
|
||||
c.addActionListener(actionListener)
|
||||
}
|
||||
|
||||
options.addListener(object : ColorAndFontSettingsListener.Abstract() {
|
||||
override fun settingsChanged() {
|
||||
if (!schemesProvider.areSchemesLoaded()) return
|
||||
if (optionsTree.selectedValue != null) {
|
||||
// update options after global state change
|
||||
processListValueChanged()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
optionsTree.apply {
|
||||
isRootVisible = false
|
||||
model = DefaultTreeModel(DefaultMutableTreeTableNode())
|
||||
selectionModel.selectionMode = TreeSelectionModel.SINGLE_TREE_SELECTION
|
||||
addTreeSelectionListener {
|
||||
if (schemesProvider.areSchemesLoaded()) {
|
||||
processListValueChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPanel(): JPanel = rootPanel
|
||||
|
||||
override fun addListener(listener: ColorAndFontSettingsListener) {
|
||||
eventDispatcher.addListener(listener)
|
||||
}
|
||||
|
||||
override fun updateOptionsList() {
|
||||
fillOptionsList()
|
||||
processListValueChanged()
|
||||
}
|
||||
|
||||
private data class DescriptionsNode(val rainbowName: String, val descriptions: List<TextAttributesDescription>) {
|
||||
override fun toString(): String = rainbowName
|
||||
}
|
||||
|
||||
private fun fillOptionsList() {
|
||||
val nodes = options.currentDescriptions.asSequence()
|
||||
.filter { it is TextAttributesDescription && it.group == category }
|
||||
.map {
|
||||
val description = it as TextAttributesDescription
|
||||
val rainbowName = description.toString().split(":")[0]
|
||||
rainbowName to description
|
||||
}
|
||||
.groupBy { it.first }
|
||||
.map { (rainbowName, descriptions) ->
|
||||
DefaultMutableTreeNode(DescriptionsNode(rainbowName,
|
||||
descriptions.asSequence().map { it.second }.toList().sortedBy { it.toString() }))
|
||||
}
|
||||
val root = DefaultMutableTreeNode()
|
||||
for (node in nodes) {
|
||||
root.add(node)
|
||||
}
|
||||
|
||||
(optionsTree.model as DefaultTreeModel).setRoot(root)
|
||||
}
|
||||
|
||||
private fun processListValueChanged() {
|
||||
var descriptionsNode = optionsTree.selectedDescriptions
|
||||
if (descriptionsNode == null) {
|
||||
properties.getValue(SELECTED_COLOR_OPTION_PROPERTY)?.let { preselected ->
|
||||
optionsTree.selectOptionByRainbowName(preselected)
|
||||
descriptionsNode = optionsTree.selectedDescriptions
|
||||
}
|
||||
}
|
||||
|
||||
descriptionsNode?.run {
|
||||
properties.setValue(SELECTED_COLOR_OPTION_PROPERTY, rainbowName)
|
||||
reset(rainbowName, descriptions)
|
||||
} ?: resetDefault()
|
||||
}
|
||||
|
||||
private fun resetDefault() {
|
||||
rainbow.isEnabled = false
|
||||
rainbow.isSelected = false
|
||||
gradientLabel.text = "Assign each brackets its own color from the spectrum below:"
|
||||
|
||||
for (i in 0 until minRange()) {
|
||||
colors[i].isEnabled = false
|
||||
colors[i].selectedColor = null
|
||||
colorLabels[i].isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun reset(rainbowName: String, descriptions: List<TextAttributesDescription>) {
|
||||
val rainbowOn = RainbowHighlighter.isRainbowEnabled(rainbowName)
|
||||
|
||||
rainbow.isEnabled = true
|
||||
rainbow.isSelected = rainbowOn
|
||||
gradientLabel.text = "Assign each ${rainbowName.toLowerCase()} its own color from the spectrum below:"
|
||||
|
||||
for (i in 0 until minRange()) {
|
||||
colors[i].isEnabled = rainbowOn
|
||||
colorLabels[i].isEnabled = rainbowOn
|
||||
colors[i].selectedColor = descriptions.indexOfOrNull(i)?.rainbowColor
|
||||
descriptions.indexOfOrNull(i)?.let { eventDispatcher.multicaster.selectedOptionChanged(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun applyChangesToScheme() {
|
||||
val scheme = options.selectedScheme
|
||||
val (rainbowName, descriptions) = optionsTree.selectedDescriptions ?: return
|
||||
when (rainbowName) {
|
||||
RainbowHighlighter.NAME_ROUND_BRACKETS,
|
||||
RainbowHighlighter.NAME_ANGLE_BRACKETS,
|
||||
RainbowHighlighter.NAME_SQUARE_BRACKETS,
|
||||
RainbowHighlighter.NAME_SQUIGGLY_BRACKETS -> {
|
||||
RainbowHighlighter.setRainbowEnabled(rainbowName, rainbow.isSelected)
|
||||
|
||||
for (i in 0 until minRange()) {
|
||||
colors[i].selectedColor?.let { color ->
|
||||
descriptions[i].rainbowColor = color
|
||||
descriptions[i].apply(scheme)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun minRange() = minOf(RainbowSettings.instance.numberOfColors, 5)
|
||||
|
||||
override fun processListOptions(): MutableSet<String> = mutableSetOf(
|
||||
RainbowHighlighter.NAME_ROUND_BRACKETS,
|
||||
RainbowHighlighter.NAME_SQUARE_BRACKETS,
|
||||
RainbowHighlighter.NAME_SQUIGGLY_BRACKETS,
|
||||
RainbowHighlighter.NAME_ANGLE_BRACKETS
|
||||
)
|
||||
|
||||
override fun showOption(option: String): Runnable? = Runnable {
|
||||
optionsTree.selectOptionByRainbowName(option)
|
||||
}
|
||||
|
||||
override fun selectOption(typeToSelect: String) {
|
||||
optionsTree.selectOptionByType(typeToSelect)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SELECTED_COLOR_OPTION_PROPERTY = "rainbow.selected.color.option.name"
|
||||
|
||||
private var TextAttributesDescription.rainbowColor: Color?
|
||||
get() = externalForeground
|
||||
set(value) {
|
||||
externalForeground = value
|
||||
}
|
||||
|
||||
private val Tree.selectedValue: Any?
|
||||
get() = (lastSelectedPathComponent as? DefaultMutableTreeNode)?.userObject
|
||||
|
||||
private val Tree.selectedDescriptions: DescriptionsNode?
|
||||
get() = selectedValue as? DescriptionsNode
|
||||
|
||||
private fun Tree.findOption(nodeObject: Any, matcher: (Any) -> Boolean): TreePath? {
|
||||
val model = model as DefaultTreeModel
|
||||
for (i in 0 until model.getChildCount(nodeObject)) {
|
||||
val childObject = model.getChild(nodeObject, i)
|
||||
if (childObject is DefaultMutableTreeNode) {
|
||||
val data = childObject.userObject
|
||||
if (matcher(data)) {
|
||||
return TreePath(model.getPathToRoot(childObject))
|
||||
}
|
||||
}
|
||||
|
||||
val pathInChild = findOption(childObject, matcher)
|
||||
if (pathInChild != null) return pathInChild
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun Tree.selectOptionByRainbowName(rainbowName: String) {
|
||||
selectPath(findOption(model.root) { data ->
|
||||
data is DescriptionsNode
|
||||
&& rainbowName.isNotBlank()
|
||||
&& data.rainbowName.contains(rainbowName, ignoreCase = true)
|
||||
})
|
||||
}
|
||||
|
||||
private fun Tree.selectOptionByType(attributeType: String) {
|
||||
selectPath(findOption(model.root) { data ->
|
||||
data is DescriptionsNode && data.descriptions.any { it.type == attributeType }
|
||||
})
|
||||
}
|
||||
|
||||
private fun Tree.selectPath(path: TreePath?) {
|
||||
if (path != null) {
|
||||
selectionPath = path
|
||||
scrollPathToVisible(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <E> List<E>.indexOfOrNull(idx: Int): E? = if (idx < this.size) this[idx] else null
|
@@ -1,137 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.settings.form
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import javax.swing.JCheckBox
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JPanel
|
||||
import javax.swing.JTextField
|
||||
|
||||
class RainbowSettingsForm {
|
||||
private var panel: JPanel? = null
|
||||
private var appearancePanel: JPanel? = null
|
||||
private var enableRainbow: JCheckBox? = null
|
||||
private var enableRainbowRoundBrackets: JCheckBox? = null
|
||||
private var enableRainbowSquigglyBrackets: JCheckBox? = null
|
||||
private var enableRainbowSquareBrackets: JCheckBox? = null
|
||||
private var enableRainbowAngleBrackets: JCheckBox? = null
|
||||
private var showRainbowIndentGuides: JCheckBox? = null
|
||||
private var doNOTRainbowifyBracketsWithoutContent: JCheckBox? = null
|
||||
private var isDoNOTRainbowifyTheFirstLevel: JCheckBox? = null
|
||||
private var pressAnyKeyToRemoveTheHighlightingEffects: JCheckBox? = null
|
||||
private var applyColorsOfRoundForAllBrackets: JCheckBox? = null
|
||||
private var cycleCountOnAllBrackets: JCheckBox? = null
|
||||
|
||||
private var numberOfColors: JTextField? = null
|
||||
|
||||
private var languageBlacklist: JTextField? = null
|
||||
|
||||
private var disableRainbowIndentsInZenMode: JCheckBox? = null
|
||||
|
||||
private var useColorGenerator: JCheckBox? = null
|
||||
|
||||
private var rainbowifyTagNameInXML: JCheckBox? = null
|
||||
|
||||
private var doNOTRainbowifyTemplateString: JCheckBox? = null
|
||||
|
||||
private var doNOTRainbowifyBigFiles: JCheckBox? = null
|
||||
|
||||
private var bigFilesLinesThreshold: JTextField? = null
|
||||
|
||||
private var rainbowifyPythonKeywords: JCheckBox? = null
|
||||
|
||||
private val settings: RainbowSettings = RainbowSettings.instance
|
||||
|
||||
fun component(): JComponent? = panel
|
||||
|
||||
fun isRainbowEnabled() = enableRainbow?.isSelected
|
||||
|
||||
fun isRainbowRoundBracketsEnabled() = enableRainbowRoundBrackets?.isSelected
|
||||
|
||||
fun isRainbowSquigglyBracketsEnabled() = enableRainbowSquigglyBrackets?.isSelected
|
||||
|
||||
fun isRainbowSquareBracketsEnabled() = enableRainbowSquareBrackets?.isSelected
|
||||
|
||||
fun isRainbowAngleBracketsEnabled() = enableRainbowAngleBrackets?.isSelected
|
||||
|
||||
fun isShowRainbowIndentGuides() = showRainbowIndentGuides?.isSelected
|
||||
|
||||
fun isDoNOTRainbowifyBracketsWithoutContent() = doNOTRainbowifyBracketsWithoutContent?.isSelected
|
||||
|
||||
fun isDoNOTRainbowifyTheFirstLevel() = isDoNOTRainbowifyTheFirstLevel?.isSelected
|
||||
|
||||
fun pressAnyKeyToRemoveTheHighlightingEffects() = pressAnyKeyToRemoveTheHighlightingEffects?.isSelected
|
||||
|
||||
fun applyColorsOfRoundForAllBrackets() = applyColorsOfRoundForAllBrackets?.isSelected
|
||||
|
||||
fun cycleCountOnAllBrackets() = cycleCountOnAllBrackets?.isSelected
|
||||
|
||||
fun numberOfColors() = numberOfColors?.text?.toIntOrNull()
|
||||
|
||||
fun languageBlacklist() =
|
||||
languageBlacklist?.text?.split(",")?.map { it.trim() }?.filterNot { it.isEmpty() }?.toSet()
|
||||
|
||||
fun disableRainbowIndentsInZenMode() = disableRainbowIndentsInZenMode?.isSelected
|
||||
|
||||
fun useColorGenerator() = useColorGenerator?.isSelected
|
||||
|
||||
fun rainbowifyTagNameInXML() = rainbowifyTagNameInXML?.isSelected
|
||||
|
||||
fun doNOTRainbowifyTemplateString() = doNOTRainbowifyTemplateString?.isSelected
|
||||
|
||||
fun doNOTRainbowifyBigFiles() = doNOTRainbowifyBigFiles?.isSelected
|
||||
|
||||
fun bigFilesLinesThreshold() = bigFilesLinesThreshold?.text?.toIntOrNull()
|
||||
|
||||
fun rainbowifyPythonKeywords() = rainbowifyPythonKeywords?.isSelected
|
||||
|
||||
val isModified: Boolean
|
||||
get() = (isRainbowEnabled() != settings.isRainbowEnabled
|
||||
|| isRainbowAngleBracketsEnabled() != settings.isEnableRainbowAngleBrackets
|
||||
|| isRainbowRoundBracketsEnabled() != settings.isEnableRainbowRoundBrackets
|
||||
|| isRainbowSquigglyBracketsEnabled() != settings.isEnableRainbowSquigglyBrackets
|
||||
|| isRainbowSquareBracketsEnabled() != settings.isEnableRainbowSquareBrackets
|
||||
|| isShowRainbowIndentGuides() != settings.isShowRainbowIndentGuides
|
||||
|| isDoNOTRainbowifyBracketsWithoutContent() != settings.isDoNOTRainbowifyBracketsWithoutContent
|
||||
|| isDoNOTRainbowifyTheFirstLevel() != settings.isDoNOTRainbowifyTheFirstLevel
|
||||
|| pressAnyKeyToRemoveTheHighlightingEffects() != settings.pressAnyKeyToRemoveTheHighlightingEffects
|
||||
|| applyColorsOfRoundForAllBrackets() != settings.applyColorsOfRoundForAllBrackets
|
||||
|| cycleCountOnAllBrackets() != settings.cycleCountOnAllBrackets
|
||||
|| numberOfColors() != settings.numberOfColors
|
||||
|| disableRainbowIndentsInZenMode() != settings.disableRainbowIndentsInZenMode
|
||||
|| useColorGenerator() != settings.useColorGenerator
|
||||
|| rainbowifyTagNameInXML() != settings.rainbowifyTagNameInXML
|
||||
|| doNOTRainbowifyTemplateString() != settings.doNOTRainbowifyTemplateString
|
||||
|| doNOTRainbowifyBigFiles() != settings.doNOTRainbowifyBigFiles
|
||||
|| bigFilesLinesThreshold() != settings.bigFilesLinesThreshold
|
||||
|| languageBlacklist() != settings.languageBlacklist
|
||||
|| rainbowifyPythonKeywords() != settings.rainbowifyPythonKeywords
|
||||
)
|
||||
|
||||
init {
|
||||
loadSettings()
|
||||
doNOTRainbowifyBigFiles?.addActionListener({e -> bigFilesLinesThreshold?.setEnabled(doNOTRainbowifyBigFiles() ?: false)})
|
||||
}
|
||||
|
||||
fun loadSettings() {
|
||||
enableRainbow?.isSelected = settings.isRainbowEnabled
|
||||
enableRainbowRoundBrackets?.isSelected = settings.isEnableRainbowRoundBrackets
|
||||
enableRainbowAngleBrackets?.isSelected = settings.isEnableRainbowAngleBrackets
|
||||
enableRainbowSquigglyBrackets?.isSelected = settings.isEnableRainbowSquigglyBrackets
|
||||
enableRainbowSquareBrackets?.isSelected = settings.isEnableRainbowSquareBrackets
|
||||
showRainbowIndentGuides?.isSelected = settings.isShowRainbowIndentGuides
|
||||
doNOTRainbowifyBracketsWithoutContent?.isSelected = settings.isDoNOTRainbowifyBracketsWithoutContent
|
||||
isDoNOTRainbowifyTheFirstLevel?.isSelected = settings.isDoNOTRainbowifyTheFirstLevel
|
||||
pressAnyKeyToRemoveTheHighlightingEffects?.isSelected = settings.pressAnyKeyToRemoveTheHighlightingEffects
|
||||
applyColorsOfRoundForAllBrackets?.isSelected = settings.applyColorsOfRoundForAllBrackets
|
||||
cycleCountOnAllBrackets?.isSelected = settings.cycleCountOnAllBrackets
|
||||
numberOfColors?.text = settings.numberOfColors.toString()
|
||||
disableRainbowIndentsInZenMode?.isSelected = settings.disableRainbowIndentsInZenMode
|
||||
useColorGenerator?.isSelected = settings.useColorGenerator
|
||||
rainbowifyTagNameInXML?.isSelected = settings.rainbowifyTagNameInXML
|
||||
doNOTRainbowifyTemplateString?.isSelected = settings.doNOTRainbowifyTemplateString
|
||||
doNOTRainbowifyBigFiles?.isSelected = settings.doNOTRainbowifyBigFiles
|
||||
bigFilesLinesThreshold?.text = settings.bigFilesLinesThreshold.toString()
|
||||
languageBlacklist?.text = settings.languageBlacklist.joinToString(",")
|
||||
rainbowifyPythonKeywords?.isSelected = settings.rainbowifyPythonKeywords
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.util
|
||||
|
||||
import java.awt.Color
|
||||
|
||||
|
||||
fun Color.alphaBlend(background: Color, alpha: Float): Color {
|
||||
require(alpha in 0.0..1.0) { "alpha(0.0 <= alpha <= 1.0): $alpha" }
|
||||
|
||||
val r = (1 - alpha) * background.red + alpha * red
|
||||
val g = (1 - alpha) * background.green + alpha * green
|
||||
val b = (1 - alpha) * background.blue + alpha * blue
|
||||
|
||||
return Color(r.toInt(), g.toInt(), b.toInt())
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.util
|
||||
|
||||
import com.intellij.openapi.diagnostic.Attachment
|
||||
import com.intellij.util.ExceptionUtil
|
||||
|
||||
data class ErrorContext(val stackTrace: String) {
|
||||
var message: String? = null
|
||||
var errorClass: String = ""
|
||||
var description: String = ""
|
||||
var pluginName: String = ""
|
||||
var pluginVersion: String = "Unknown"
|
||||
var attachments: List<Attachment> = emptyList()
|
||||
|
||||
companion object {
|
||||
fun fromThrowable(throwable: Throwable): ErrorContext {
|
||||
val throwableText = ExceptionUtil.getThrowableText(throwable)
|
||||
val errorContext = ErrorContext(throwableText)
|
||||
errorContext.message = throwable.message
|
||||
val firstLine = throwableText.lines()[0]
|
||||
errorContext.errorClass = firstLine.substringBeforeLast(':')
|
||||
return errorContext
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.util
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
fun <A, R> ((A) -> R).memoize(): (A) -> R = object : (A) -> R {
|
||||
private val m = MemoizedHandler<((A) -> R), MemoizeKey1<A, R>, R>(this@memoize)
|
||||
override fun invoke(a: A) = m(MemoizeKey1(a))
|
||||
}
|
||||
|
||||
fun <A, B, R> ((A, B) -> R).memoize(): (A, B) -> R = object : (A, B) -> R {
|
||||
private val m = MemoizedHandler<((A, B) -> R), MemoizeKey2<A, B, R>, R>(this@memoize)
|
||||
override fun invoke(a: A, b: B) = m(MemoizeKey2(a, b))
|
||||
}
|
||||
|
||||
fun <A, B, C, R> ((A, B, C) -> R).memoize(): (A, B, C) -> R = object : (A, B, C) -> R {
|
||||
private val m = MemoizedHandler<((A, B, C) -> R), MemoizeKey3<A, B, C, R>, R>(this@memoize)
|
||||
override fun invoke(a: A, b: B, c: C) = m(MemoizeKey3(a, b, c))
|
||||
}
|
||||
|
||||
|
||||
private interface MemoizedCall<in F, out R> {
|
||||
operator fun invoke(f: F): R
|
||||
}
|
||||
|
||||
private class MemoizedHandler<F, in K : MemoizedCall<F, R>, out R>(val f: F) {
|
||||
private val m = Platform.newConcurrentMap<K, R>()
|
||||
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> {
|
||||
override fun invoke(f: (A) -> R) = f(a)
|
||||
}
|
||||
|
||||
private data class MemoizeKey2<out A, out B, R>(val a: A, val b: B) : MemoizedCall<(A, B) -> R, R> {
|
||||
override fun invoke(f: (A, B) -> R) = f(a, b)
|
||||
}
|
||||
|
||||
private data class MemoizeKey3<out A, out B, out C, R>(val a: A, val b: B, val c: C) : MemoizedCall<(A, B, C) -> R, R> {
|
||||
override fun invoke(f: (A, B, C) -> R) = f(a, b, c)
|
||||
}
|
||||
|
||||
object Platform {
|
||||
|
||||
interface ConcurrentMap<K, V> : MutableMap<K, V> {
|
||||
fun putSafely(k: K, v: V): V
|
||||
}
|
||||
|
||||
fun <K, V> newConcurrentMap(): ConcurrentMap<K, V> {
|
||||
val map by lazy { ConcurrentHashMap<K, V>() }
|
||||
return object : ConcurrentMap<K, V>, MutableMap<K, V> by map {
|
||||
override fun putSafely(k: K, v: V): V =
|
||||
map.putIfAbsent(k, v) ?: v
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.util
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import java.io.File
|
||||
|
||||
fun File.toPsiFile(project: Project): PsiFile? = toVirtualFile()?.toPsiFile(project)
|
||||
|
||||
fun File.toVirtualFile(): VirtualFile? = LocalFileSystem.getInstance().findFileByIoFile(this)
|
||||
|
||||
fun File.toPsiDirectory(project: Project): PsiDirectory? {
|
||||
return toVirtualFile()?.let { vfile -> PsiManager.getInstance(project).findDirectory(vfile) }
|
||||
}
|
||||
|
||||
fun VirtualFile.toPsiFile(project: Project): PsiFile? = PsiManager.getInstance(project).findFile(this)
|
||||
|
||||
fun VirtualFile.toPsiDirectory(project: Project): PsiDirectory? = PsiManager.getInstance(project).findDirectory(this)
|
@@ -1,171 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.visitor
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.bracePairs
|
||||
import com.github.izhangzhihao.rainbow.brackets.braceTypeSet
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
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
|
||||
|
||||
|
||||
class DefaultRainbowVisitor : RainbowHighlightVisitor() {
|
||||
|
||||
override fun clone(): HighlightVisitor = DefaultRainbowVisitor()
|
||||
|
||||
override fun visit(element: PsiElement) {
|
||||
val type = (element as? LeafPsiElement)?.elementType ?: return
|
||||
val matching = filterPairs(type, element) ?: return
|
||||
|
||||
val pair =
|
||||
if (matching.size == 1) {
|
||||
matching[0]
|
||||
} else {
|
||||
matching.find { element.isValidBracket(it) }
|
||||
} ?: return
|
||||
|
||||
val level = element.getBracketLevel(pair)
|
||||
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 {
|
||||
|
||||
private fun LeafPsiElement.getBracketLevel(pair: BracePair): Int = iterateBracketParents(parent, pair, -1)
|
||||
|
||||
private tailrec fun iterateBracketParents(element: PsiElement?, pair: BracePair, count: Int): Int {
|
||||
if (element == null || element is PsiFile) {
|
||||
return count
|
||||
}
|
||||
|
||||
var nextCount = count
|
||||
if (!RainbowSettings.instance.cycleCountOnAllBrackets) {
|
||||
if (element.haveBrackets({ it.elementType() == pair.leftBraceType },
|
||||
{ it.elementType() == pair.rightBraceType })
|
||||
) {
|
||||
nextCount++
|
||||
}
|
||||
} else {
|
||||
if (element.haveBrackets({ element.language.braceTypeSet.contains(it.elementType()) },
|
||||
{ element.language.braceTypeSet.contains(it.elementType()) })
|
||||
) {
|
||||
nextCount++
|
||||
}
|
||||
}
|
||||
|
||||
return iterateBracketParents(element.parent, pair, nextCount)
|
||||
}
|
||||
|
||||
private inline fun PsiElement.haveBrackets(
|
||||
checkLeft: (PsiElement) -> Boolean,
|
||||
checkRight: (PsiElement) -> Boolean
|
||||
): Boolean {
|
||||
if (this is LeafPsiElement) {
|
||||
return false
|
||||
}
|
||||
|
||||
var findLeftBracket = false
|
||||
var findRightBracket = false
|
||||
var left: PsiElement? = firstChild
|
||||
var right: PsiElement? = lastChild
|
||||
while (left != right && (!findLeftBracket || !findRightBracket)) {
|
||||
val needBreak = left == null || left.nextSibling == right
|
||||
|
||||
if (left is LeafPsiElement && checkLeft(left)) {
|
||||
findLeftBracket = true
|
||||
} else {
|
||||
left = left?.nextSibling
|
||||
}
|
||||
if (right is LeafPsiElement && checkRight(right)) {
|
||||
findRightBracket = true
|
||||
} else {
|
||||
right = right?.prevSibling
|
||||
}
|
||||
|
||||
if (needBreak) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//For https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/830
|
||||
if (RainbowSettings.instance.doNOTRainbowifyTemplateString) {
|
||||
if (left?.prevSibling?.textMatches("$") == true) return false
|
||||
}
|
||||
|
||||
return findLeftBracket && findRightBracket
|
||||
}
|
||||
|
||||
private fun PsiElement.elementType(): IElementType? {
|
||||
return (this as? LeafPsiElement)?.elementType
|
||||
}
|
||||
|
||||
private fun LeafPsiElement.isValidBracket(pair: BracePair): Boolean {
|
||||
val pairType = when (elementType) {
|
||||
pair.leftBraceType -> pair.rightBraceType
|
||||
pair.rightBraceType -> pair.leftBraceType
|
||||
else -> return false
|
||||
}
|
||||
|
||||
return if (pairType == pair.leftBraceType) {
|
||||
checkBracePair(this, parent.firstChild, pairType, PsiElement::getNextSibling)
|
||||
} else {
|
||||
checkBracePair(this, parent.lastChild, pairType, PsiElement::getPrevSibling)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkBracePair(
|
||||
brace: PsiElement,
|
||||
start: PsiElement,
|
||||
type: IElementType,
|
||||
next: PsiElement.() -> PsiElement?
|
||||
): Boolean {
|
||||
var element: PsiElement? = start
|
||||
while (element != null && element != brace) {
|
||||
if (element is LeafPsiElement && element.elementType == type) {
|
||||
return true
|
||||
}
|
||||
|
||||
element = element.next()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun filterPairs(type: IElementType, element: LeafPsiElement): List<BracePair>? {
|
||||
val pairs = element.language.bracePairs ?: return null
|
||||
val filterBraceType = pairs[type.toString()]
|
||||
return when {
|
||||
filterBraceType == null || filterBraceType.isEmpty() -> {
|
||||
null
|
||||
}
|
||||
// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/198
|
||||
element.javaClass.simpleName == "OCMacroForeignLeafElement" -> {
|
||||
null
|
||||
}
|
||||
RainbowSettings.instance.isDoNOTRainbowifyBracketsWithoutContent -> {
|
||||
filterBraceType
|
||||
.filterNot { it.leftBraceType == type && element.nextSibling?.elementType() == it.rightBraceType }
|
||||
.filterNot { it.rightBraceType == type && element.prevSibling?.elementType() == it.leftBraceType }
|
||||
}
|
||||
else -> {
|
||||
filterBraceType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.visitor
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.github.izhangzhihao.rainbow.brackets.visitor.XmlRainbowVisitor.Companion.iterateXmlTagParents
|
||||
import com.github.izhangzhihao.rainbow.brackets.visitor.XmlRainbowVisitor.Companion.xmlParent
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.xml.XmlTag
|
||||
import com.intellij.psi.xml.XmlToken
|
||||
import com.intellij.psi.xml.XmlTokenType
|
||||
|
||||
|
||||
class PugRainbowVisitor : RainbowHighlightVisitor() {
|
||||
|
||||
override fun suitableForFile(file: PsiFile)
|
||||
: Boolean = super.suitableForFile(file) &&
|
||||
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
||||
(file.language.id == "Jade" ||
|
||||
file.viewProvider.allFiles.any { it.language.id == "Jade" } ||
|
||||
file.name.endsWith(".vue")
|
||||
)
|
||||
|
||||
override fun clone(): HighlightVisitor = PugRainbowVisitor()
|
||||
|
||||
override fun visit(element: PsiElement) {
|
||||
if (element !is XmlToken) {
|
||||
return
|
||||
}
|
||||
|
||||
if (element.tokenType == XmlTokenType.XML_TAG_NAME) {
|
||||
val parent = element.parent
|
||||
if (parent != null && parent is XmlTag) {
|
||||
parent.level.let { element.setHighlightInfo(element.xmlParent, it, element, null) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val XmlTag.level: Int
|
||||
get() = iterateXmlTagParents(parent, 0)
|
||||
}
|
||||
}
|
@@ -1,102 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.visitor
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.jetbrains.python.PyTokenTypes.BREAK_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.CLASS_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.CONTINUE_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.DEF_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.ELIF_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.ELSE_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.EXCEPT_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.FINALLY_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.FOR_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.IF_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.RAISE_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.RETURN_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.TRY_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.WHILE_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.WITH_KEYWORD
|
||||
import com.jetbrains.python.PyTokenTypes.YIELD_KEYWORD
|
||||
import com.jetbrains.python.psi.PyStatement
|
||||
|
||||
|
||||
class PythonRainbowVisitor : RainbowHighlightVisitor() {
|
||||
|
||||
override fun suitableForFile(file: PsiFile)
|
||||
: Boolean = super.suitableForFile(file) &&
|
||||
RainbowSettings.instance.rainbowifyPythonKeywords &&
|
||||
(file.language.id == "Python" ||
|
||||
file.viewProvider.allFiles.any { it.language.id == "Python" }
|
||||
)
|
||||
|
||||
override fun clone(): HighlightVisitor = PythonRainbowVisitor()
|
||||
|
||||
override fun visit(element: PsiElement) {
|
||||
val type = (element as? LeafPsiElement)?.elementType ?: return
|
||||
val exists = statementKeywords.contains(type)
|
||||
if (exists) {
|
||||
val level = element.getBracketLevel()
|
||||
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
||||
if (level >= 1) {
|
||||
rainbowPairs(element, level)
|
||||
}
|
||||
} else {
|
||||
if (level >= 0) {
|
||||
rainbowPairs(element, level)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun rainbowPairs(element: LeafPsiElement, level: Int) {
|
||||
element.setHighlightInfo(element.parent, level, element, element)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val statementKeywords = setOf(
|
||||
IF_KEYWORD,
|
||||
ELSE_KEYWORD,
|
||||
ELIF_KEYWORD,
|
||||
BREAK_KEYWORD,
|
||||
CONTINUE_KEYWORD,
|
||||
CLASS_KEYWORD,
|
||||
DEF_KEYWORD,
|
||||
EXCEPT_KEYWORD,
|
||||
FINALLY_KEYWORD,
|
||||
FOR_KEYWORD,
|
||||
RAISE_KEYWORD,
|
||||
RETURN_KEYWORD,
|
||||
TRY_KEYWORD,
|
||||
WITH_KEYWORD,
|
||||
WHILE_KEYWORD,
|
||||
YIELD_KEYWORD,
|
||||
)
|
||||
|
||||
private fun LeafPsiElement.getBracketLevel(): Int =
|
||||
iterateBracketParents(this, -1)
|
||||
|
||||
private tailrec fun iterateBracketParents(
|
||||
element: PsiElement?,
|
||||
count: Int
|
||||
): Int {
|
||||
if (element == null || element is PsiFile) {
|
||||
return count
|
||||
}
|
||||
|
||||
var nextCount = count
|
||||
|
||||
if (element is PyStatement) {
|
||||
nextCount++
|
||||
}
|
||||
|
||||
return iterateBracketParents(
|
||||
element.parent,
|
||||
nextCount,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,114 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.visitor
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter.getHighlightInfo
|
||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.github.izhangzhihao.rainbow.brackets.util.memoizedFileExtension
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import java.awt.Color
|
||||
|
||||
|
||||
abstract class RainbowHighlightVisitor : HighlightVisitor {
|
||||
|
||||
private var highlightInfoHolder: HighlightInfoHolder? = null
|
||||
|
||||
override fun suitableForFile(file: PsiFile): Boolean {
|
||||
return RainbowSettings.instance.isRainbowEnabled &&
|
||||
checkForBigFile(file) &&
|
||||
!RainbowSettings.instance.languageBlacklist.contains(file.fileType.name) &&
|
||||
!RainbowSettings.instance.languageBlacklist.contains(memoizedFileExtension(file.name)) &&
|
||||
fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(file.fileType.name)
|
||||
}
|
||||
|
||||
final override fun analyze(file: PsiFile, updateWholeFile: Boolean, holder: HighlightInfoHolder, action: Runnable): Boolean {
|
||||
highlightInfoHolder = holder
|
||||
onBeforeAnalyze(file, updateWholeFile)
|
||||
try {
|
||||
action.run()
|
||||
} catch (e: Throwable) {
|
||||
} finally {
|
||||
onAfterAnalyze()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
protected open fun onBeforeAnalyze(file: PsiFile, updateWholeFile: Boolean) = Unit
|
||||
|
||||
protected open fun onAfterAnalyze() {
|
||||
highlightInfoHolder = null
|
||||
}
|
||||
|
||||
protected fun PsiElement.setHighlightInfo(parent: PsiElement?,
|
||||
level: Int,
|
||||
startElement: PsiElement?,
|
||||
endElement: PsiElement?) {
|
||||
val holder = highlightInfoHolder ?: return
|
||||
val globalScheme = EditorColorsManager.getInstance().globalScheme
|
||||
getHighlightInfo(globalScheme, this, level)
|
||||
?.also {
|
||||
holder.add(it)
|
||||
|
||||
if (startElement != null || endElement != null) {
|
||||
val color: Color? = globalScheme.getAttributes(it.forcedTextAttributesKey)?.foregroundColor
|
||||
color?.let {
|
||||
parent?.saveRainbowInfo(level, color, startElement, endElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiElement.saveRainbowInfo(level: Int,
|
||||
color: Color,
|
||||
startElement: PsiElement?,
|
||||
endElement: PsiElement?) {
|
||||
val rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[this]?.also {
|
||||
it.level = level
|
||||
it.color = color
|
||||
} ?: RainbowInfo(level, color).also { RainbowInfo.RAINBOW_INFO_KEY[this] = it }
|
||||
|
||||
startElement?.let { rainbowInfo.startElement = it }
|
||||
endElement?.let { rainbowInfo.endElement = it }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val isIntelliJHaskellEnabled: Boolean by lazy {
|
||||
PluginManagerCore.getPlugin(
|
||||
PluginId.getId("intellij.haskell"))?.isEnabled ?: false
|
||||
}
|
||||
|
||||
fun checkForBigFile(file: PsiFile): Boolean =
|
||||
!(RainbowSettings.instance.doNOTRainbowifyBigFiles &&
|
||||
file.getLineCount() > RainbowSettings.instance.bigFilesLinesThreshold)
|
||||
|
||||
private fun fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(fileType: String) =
|
||||
fileType != "Haskell" || !isIntelliJHaskellEnabled
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiElement.getLineCount(): Int {
|
||||
try {
|
||||
val doc = containingFile?.let { PsiDocumentManager.getInstance(project).getDocument(it) }
|
||||
if (doc != null) {
|
||||
val spaceRange = textRange ?: TextRange.EMPTY_RANGE
|
||||
|
||||
if (spaceRange.endOffset <= doc.textLength && spaceRange.startOffset < spaceRange.endOffset) {
|
||||
val startLine = doc.getLineNumber(spaceRange.startOffset)
|
||||
val endLine = doc.getLineNumber(spaceRange.endOffset - 1)
|
||||
|
||||
return endLine - startLine + 1
|
||||
}
|
||||
}
|
||||
return StringUtil.getLineBreakCount(text ?: "") + 1
|
||||
} catch (e: Throwable) {
|
||||
return 0
|
||||
}
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.visitor
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import com.intellij.lang.javascript.DialectDetector
|
||||
import com.intellij.psi.PsiFile
|
||||
|
||||
class ReactJSXRainbowVisitor : XmlRainbowVisitor() {
|
||||
|
||||
override fun suitableForFile(file: PsiFile): Boolean {
|
||||
return DialectDetector.isJSX(file)
|
||||
}
|
||||
|
||||
override fun clone(): HighlightVisitor {
|
||||
return ReactJSXRainbowVisitor()
|
||||
}
|
||||
}
|
@@ -1,98 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.visitor
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.xml.XmlFile
|
||||
import com.intellij.psi.xml.XmlTag
|
||||
import com.intellij.psi.xml.XmlToken
|
||||
import com.intellij.psi.xml.XmlTokenType
|
||||
|
||||
|
||||
open class XmlRainbowVisitor : RainbowHighlightVisitor() {
|
||||
|
||||
override fun suitableForFile(file: PsiFile)
|
||||
: Boolean = super.suitableForFile(file) &&
|
||||
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
||||
(file is XmlFile || file.viewProvider.allFiles.any { it is XmlFile })
|
||||
|
||||
override fun clone(): HighlightVisitor = XmlRainbowVisitor()
|
||||
|
||||
override fun visit(element: PsiElement) {
|
||||
if (element !is XmlToken) {
|
||||
return
|
||||
}
|
||||
|
||||
when (val tokenType = element.tokenType) {
|
||||
XmlTokenType.XML_DOCTYPE_START,
|
||||
XmlTokenType.XML_DOCTYPE_END,
|
||||
XmlTokenType.XML_PI_START,
|
||||
XmlTokenType.XML_PI_END -> {
|
||||
val startElement = element.takeIf {
|
||||
tokenType == XmlTokenType.XML_DOCTYPE_START || tokenType == XmlTokenType.XML_PI_START
|
||||
}
|
||||
val endElement = element.takeIf {
|
||||
tokenType == XmlTokenType.XML_DOCTYPE_END || tokenType == XmlTokenType.XML_PI_END
|
||||
}
|
||||
element.setHighlightInfo(element.xmlParent, 0, startElement, endElement)
|
||||
}
|
||||
|
||||
XmlTokenType.XML_START_TAG_START,
|
||||
XmlTokenType.XML_END_TAG_START,
|
||||
XmlTokenType.XML_TAG_END,
|
||||
XmlTokenType.XML_EMPTY_ELEMENT_END -> {
|
||||
val startElement = element.takeIf { tokenType == XmlTokenType.XML_START_TAG_START }
|
||||
val endElement = element.takeIf {
|
||||
tokenType == XmlTokenType.XML_TAG_END || tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END
|
||||
}
|
||||
element.level?.let { element.setHighlightInfo(element.xmlParent, it, startElement, endElement) }
|
||||
}
|
||||
|
||||
XmlTokenType.XML_CDATA_START,
|
||||
XmlTokenType.XML_CDATA_END -> {
|
||||
val startElement = element.takeIf { tokenType == XmlTokenType.XML_CDATA_START }
|
||||
val endElement = element.takeIf { tokenType == XmlTokenType.XML_CDATA_END }
|
||||
element.level?.let { element.setHighlightInfo(element.parent, it + 1, startElement, endElement) }
|
||||
}
|
||||
|
||||
XmlTokenType.XML_TAG_NAME,
|
||||
XmlTokenType.XML_NAME -> {
|
||||
if (RainbowSettings.instance.rainbowifyTagNameInXML) {
|
||||
val prevSibling = element.prevSibling
|
||||
if (prevSibling != null && prevSibling is XmlToken) {
|
||||
prevSibling.level?.let { element.setHighlightInfo(element.xmlParent, it, element, null) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val PsiElement.xmlParent: PsiElement?
|
||||
get() {
|
||||
var pElement = parent
|
||||
while (pElement != null && pElement !is XmlTag && pElement !is PsiFile) {
|
||||
pElement = pElement.parent
|
||||
}
|
||||
|
||||
return pElement
|
||||
}
|
||||
|
||||
tailrec fun iterateXmlTagParents(element: PsiElement?, count: Int): Int {
|
||||
if (element == null || element is PsiFile) {
|
||||
return count
|
||||
}
|
||||
|
||||
var nextCount = count
|
||||
if (element is XmlTag) {
|
||||
nextCount++
|
||||
}
|
||||
|
||||
return iterateXmlTagParents(element.parent, nextCount)
|
||||
}
|
||||
|
||||
private val XmlToken.level: Int?
|
||||
get() = iterateXmlTagParents(parent, -1).takeIf { it >= 0 }
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.ReactJSXRainbowVisitor"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="JavaScript"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.TSBracePairProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,6 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="Dart"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.DartBracePairProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,6 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="GoTemplate"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.GoTemplateProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,6 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="Groovy"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.GroovyBracePairProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,5 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<annotator language="Haskell" implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.RainbowAnnotator"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,5 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.PugRainbowVisitor"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,12 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="kotlin"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.KotlinBracePairProvider"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<annotator language="kotlin"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.KotlinLambdaExpressionArrowAnnotator"/>
|
||||
<annotator language="kotlin"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.KotlinLabelAnnotator"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,6 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="PHP"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.PHPBracePairProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,106 +0,0 @@
|
||||
<idea-plugin require-restart="true">
|
||||
<id>com.chylex.intellij.rainbowbrackets</id>
|
||||
<name>Rainbow Brackets</name>
|
||||
<vendor url="https://chylex.com">chylex</vendor>
|
||||
|
||||
<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>.
|
||||
]]></description>
|
||||
|
||||
<change-notes><![CDATA[
|
||||
<p>6.26-chylex-3</p>
|
||||
<ul>
|
||||
<li>Prepared fork for standalone release.</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
<p>6.26-chylex-2</p>
|
||||
<ul>
|
||||
<li>Fixed Rider support.</li>
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
<p>6.26-chylex-1</p>
|
||||
<ul>
|
||||
<li>Removed post-update notification.</li>
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
<p>6.26</p>
|
||||
<ul>
|
||||
<li>Original version the fork is based on.</li>
|
||||
</ul>
|
||||
]]>
|
||||
</change-notes>
|
||||
|
||||
<!-- please see https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html
|
||||
on how to target different products -->
|
||||
<depends>com.intellij.modules.lang</depends>
|
||||
<depends optional="true" config-file="kotlin-brackets.xml">org.jetbrains.kotlin</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="groovy-brackets.xml">org.intellij.groovy</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="sql-brackets.xml">com.intellij.database</depends>
|
||||
<depends optional="true" config-file="oc-brackets.xml">com.intellij.modules.clion</depends>
|
||||
<depends optional="true" config-file="sh-brackets.xml">com.jetbrains.sh</depends>
|
||||
<depends optional="true" config-file="php-brackets.xml">com.jetbrains.php</depends>
|
||||
<depends optional="true" config-file="go-template-brackets.xml">org.jetbrains.plugins.go-template</depends>
|
||||
<depends optional="true" config-file="jade-rainbow-visitor.xml">com.jetbrains.plugins.jade</depends>
|
||||
<depends optional="true" config-file="python-brackets.xml">com.intellij.modules.python</depends>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint name="bracePairProvider" beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
|
||||
<with attribute="implementationClass"
|
||||
implements="com.github.izhangzhihao.rainbow.brackets.provider.BracePairProvider"/>
|
||||
</extensionPoint>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<!--test only-->
|
||||
<!--<annotator language="JAVA" implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.RainbowAnnotator"/>-->
|
||||
|
||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.DefaultRainbowVisitor"/>
|
||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.XmlRainbowVisitor"/>
|
||||
|
||||
<applicationConfigurable instance="com.github.izhangzhihao.rainbow.brackets.settings.RainbowConfigurable"/>
|
||||
<applicationService
|
||||
serviceImplementation="com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings"/>
|
||||
<colorAndFontPanelFactory
|
||||
implementation="com.github.izhangzhihao.rainbow.brackets.settings.RainbowColorsPageFactory"/>
|
||||
<colorAndFontDescriptorProvider
|
||||
implementation="com.github.izhangzhihao.rainbow.brackets.settings.RainbowColorsPageFactory"/>
|
||||
|
||||
<additionalTextAttributes scheme="Default" file="colorSchemes/rainbow-color-default.xml"/>
|
||||
<additionalTextAttributes scheme="Darcula" file="colorSchemes/rainbow-color-default-darcula.xml"/>
|
||||
<!--<errorHandler implementation="com.github.izhangzhihao.rainbow.brackets.util.GitHubErrorReporter"/>-->
|
||||
<highlightingPassFactory implementation="com.github.izhangzhihao.rainbow.brackets.indents.RainbowIndentsPassFactory"/>
|
||||
<editorNotificationProvider implementation="com.github.izhangzhihao.rainbow.brackets.RainbowifyBanner"/>
|
||||
<notificationGroup id="Rainbow Brackets Notification Group" displayType="STICKY_BALLOON"/>
|
||||
</extensions>
|
||||
|
||||
<applicationListeners>
|
||||
<listener class="com.github.izhangzhihao.rainbow.brackets.listener.RainbowColorsSchemeListener" topic="com.intellij.openapi.editor.colors.EditorColorsListener"/>
|
||||
</applicationListeners>
|
||||
|
||||
<actions>
|
||||
<action class="com.github.izhangzhihao.rainbow.brackets.action.ScopeHighlightingAction"
|
||||
id="Rainbow.ScopeHighlightingAction"
|
||||
text="Highlight Current Scope"
|
||||
description="Highlight current scope.">
|
||||
<mouse-shortcut keymap="$default" keystroke="control button3"/>
|
||||
<mouse-shortcut keymap="Mac OS X" keystroke="meta button3"/>
|
||||
<mouse-shortcut keymap="Mac OS X 10.5+" keystroke="meta button3"/>
|
||||
</action>
|
||||
<action class="com.github.izhangzhihao.rainbow.brackets.action.ScopeOutsideHighlightingRestrainAction"
|
||||
id="Rainbow.ScopeOutsideHighlightingRestrainAction"
|
||||
text="Restrain Scope Highlighting"
|
||||
description="Restrain outside of current scope highlighting.">
|
||||
<mouse-shortcut keymap="$default" keystroke="alt button3"/>
|
||||
<mouse-shortcut keymap="Mac OS X" keystroke="alt button3"/>
|
||||
<mouse-shortcut keymap="Mac OS X 10.5+" keystroke="alt button3"/>
|
||||
</action>
|
||||
</actions>
|
||||
|
||||
</idea-plugin>
|
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 400 400"><defs><path id="a35NhMpHdG" d="M400 200C400 310.38 310.38 400 200 400C89.62 400 0 310.38 0 200C0 89.62 89.62 0 200 0C310.38 0 400 89.62 400 200Z"/><path id="b84wADd12" d="M57.5 294C51.5 294 47.5 294 43.5 293C39.5 292 35.5 289 32.5 285C29.5 281 28.5 277 27.5 272C26.5 267 26.5 258 26.5 246C26.5 237 26.5 231 25.5 226C24.5 221 22.5 216 19.5 213C16.5 210 12.5 208 6.5 208C6.5 206.4 6.5 193.6 6.5 192C12.5 192 16.5 190 19.5 187C22.5 184 24.5 179 25.5 174C26.5 169 26.5 163 26.5 154C26.5 142 26.5 133 27.5 128C28.5 123 29.5 119 32.5 115C35.5 111 39.5 108 43.5 107C47.5 106 51.5 106 57.5 106C57.83 106 59.5 106 62.5 106L62.5 121C60.7 121 59.7 121 59.5 121C52.5 121 48.5 122 46.5 124C43.5 127 42.5 128 42.5 131C42.5 133.5 42.5 153.5 42.5 156C42.5 171 40.5 181 37.5 187C34.5 193 28.5 197 22.5 200C28.5 203 34.5 207 37.5 213C40.5 219 42.5 229 42.5 244C42.5 246.5 42.5 266.5 42.5 269C42.5 272 43.5 273 46.5 276C48.5 278 52.5 279 59.5 279C59.7 279 60.7 279 62.5 279L62.5 294C59.5 294 57.83 294 57.5 294Z"/><path id="f5MtdfUl6" d="M71.5 249C65.5 232 62.5 216 62.5 200C62.5 184 65.5 168 71.5 151C77.5 135 88.5 120 97.5 106C98.7 106 108.3 106 109.5 106C90.5 137 80.5 169 80.5 200C80.5 231 90.5 263 109.5 294C108.7 294 104.7 294 97.5 294C84.17 274.67 75.5 259.67 71.5 249Z"/><path id="ioNZw7HPO" d="M100 249L100 231L175 200L100 169L100 151L195 191L195 209L100 249Z"/><path id="i1M6XmCDiH" d="M300 249L300 231L225 200L300 169L300 151L205 191L205 209L300 249Z"/><path id="aVt4k34p4" d="M342.5 294C348.5 294 352.5 294 356.5 293C360.5 292 364.5 289 367.5 285C370.5 281 371.5 277 372.5 272C373.5 267 373.5 258 373.5 246C373.5 237 373.5 231 374.5 226C375.5 221 377.5 216 380.5 213C383.5 210 387.5 208 393.5 208C393.5 206.4 393.5 193.6 393.5 192C387.5 192 383.5 190 380.5 187C377.5 184 375.5 179 374.5 174C373.5 169 373.5 163 373.5 154C373.5 142 373.5 133 372.5 128C371.5 123 370.5 119 367.5 115C364.5 111 360.5 108 356.5 107C352.5 106 348.5 106 342.5 106C342.17 106 340.5 106 337.5 106L337.5 121C339.3 121 340.3 121 340.5 121C347.5 121 351.5 122 353.5 124C356.5 127 357.5 128 357.5 131C357.5 133.5 357.5 153.5 357.5 156C357.5 171 359.5 181 362.5 187C365.5 193 371.5 197 377.5 200C371.5 203 365.5 207 362.5 213C359.5 219 357.5 229 357.5 244C357.5 246.5 357.5 266.5 357.5 269C357.5 272 356.5 273 353.5 276C351.5 278 347.5 279 340.5 279C340.3 279 339.3 279 337.5 279L337.5 294C340.5 294 342.17 294 342.5 294Z"/><path id="eCfOjpO8n" d="M328.5 249C334.5 232 337.5 216 337.5 200C337.5 184 334.5 168 328.5 151C322.5 135 311.5 120 302.5 106C301.3 106 291.7 106 290.5 106C309.5 137 319.5 169 319.5 200C319.5 231 309.5 263 290.5 294C291.3 294 295.3 294 302.5 294C315.83 274.67 324.5 259.67 328.5 249Z"/></defs><g><g><g><use fill="#263238" fill-opacity="1" opacity="1" xlink:href="#a35NhMpHdG"/></g><g><use fill="#e6b422" fill-opacity="1" opacity="1" xlink:href="#b84wADd12"/><g><use fill-opacity="0" stroke="#000" stroke-opacity="0" stroke-width="1" opacity="1" xlink:href="#b84wADd12"/></g></g><g><use fill="#2196f3" fill-opacity="1" opacity="1" xlink:href="#f5MtdfUl6"/><g><use fill-opacity="0" stroke="#000" stroke-opacity="0" stroke-width="1" opacity="1" xlink:href="#f5MtdfUl6"/></g></g><g><use fill="#3f51b5" fill-opacity="1" opacity="1" xlink:href="#ioNZw7HPO"/><g><use fill-opacity="0" stroke="#000" stroke-opacity="0" stroke-width="1" opacity="1" xlink:href="#ioNZw7HPO"/></g></g><g><use fill="#3f51b5" fill-opacity="1" opacity="1" xlink:href="#i1M6XmCDiH"/><g><use fill-opacity="0" stroke="#000" stroke-opacity="0" stroke-width="1" opacity="1" xlink:href="#i1M6XmCDiH"/></g></g><g><use fill="#e6b422" fill-opacity="1" opacity="1" xlink:href="#aVt4k34p4"/><g><use fill-opacity="0" stroke="#000" stroke-opacity="0" stroke-width="1" opacity="1" xlink:href="#aVt4k34p4"/></g></g><g><use fill="#2196f3" fill-opacity="1" opacity="1" xlink:href="#eCfOjpO8n"/><g><use fill-opacity="0" stroke="#000" stroke-opacity="0" stroke-width="1" opacity="1" xlink:href="#eCfOjpO8n"/></g></g></g></g></svg>
|
Before Width: | Height: | Size: 4.0 KiB |
@@ -1,5 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.PythonRainbowVisitor"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,6 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="Shell Script"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.SHBracePairProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,6 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<bracePairProvider language="SQL"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.SqlBracePairProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,209 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<list>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="E8BA36"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="54A857"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="359FF4"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="5060BB"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="179387"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A5BE00"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="005FA3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="DB7100"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="FFC666"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="38FF91"/>
|
||||
</value>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="E8BA36"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="54A857"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="359FF4"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="5060BB"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="179387"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A5BE00"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="005FA3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="DB7100"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="FFC666"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="38FF91"/>
|
||||
</value>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="E8BA36"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="54A857"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="359FF4"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="5060BB"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="179387"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A5BE00"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="005FA3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="DB7100"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="FFC666"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="38FF91"/>
|
||||
</value>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="E8BA36"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="54A857"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="359FF4"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="5060BB"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="179387"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A5BE00"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="005FA3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="DB7100"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="FFC666"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="38FF91"/>
|
||||
</value>
|
||||
</option>
|
||||
</list>
|
@@ -1,209 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<list>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3F9101"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="0E4A8E"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BCBF01"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BC0BA2"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="61AA0D"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3D017A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="D6A60A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="7710A3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A502CE"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ROUND_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="eb5a00"/>
|
||||
</value>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3F9101"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="0E4A8E"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BCBF01"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BC0BA2"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="61AA0D"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3D017A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="D6A60A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="7710A3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A502CE"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUARE_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="eb5a00"/>
|
||||
</value>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3F9101"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="0E4A8E"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BCBF01"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BC0BA2"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="61AA0D"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3D017A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="D6A60A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="7710A3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A502CE"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="SQUIGGLY_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="eb5a00"/>
|
||||
</value>
|
||||
</option>
|
||||
|
||||
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR0">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3F9101"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR1">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="0E4A8E"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR2">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BCBF01"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR3">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="BC0BA2"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR4">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="61AA0D"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR5">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="3D017A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR6">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="D6A60A"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR7">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="7710A3"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR8">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="A502CE"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ANGLE_BRACKETS_RAINBOW_COLOR9">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="eb5a00"/>
|
||||
</value>
|
||||
</option>
|
||||
</list>
|
@@ -1,56 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.jetbrains.lang.dart.DartFileType
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowDartTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun testRainbowForDart() {
|
||||
val code =
|
||||
"""
|
||||
void fn(List<int> a) => print(a);
|
||||
|
||||
void main() {
|
||||
var list = <int>[];
|
||||
list.add(1);
|
||||
list.add(2);
|
||||
fn(list);
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(DartFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(0),
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
squareLevel(0),
|
||||
squareLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowGroovyTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun testRainbowForGroovy() {
|
||||
@Language("Groovy") val code =
|
||||
"""
|
||||
Map<String, Map<String, String>> convertObjectsToMapProperties(Map<String, Object> body) {
|
||||
return body.collectEntries {
|
||||
Map.Entry<String, Object> entry ->
|
||||
[entry.key: entry.value]
|
||||
} as Map<String, Map<String, String>>
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(GroovyFileType.GROOVY_FILE_TYPE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(0),
|
||||
|
||||
roundLevel(0),
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(1),
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
squareLevel(0),
|
||||
|
||||
squareLevel(0),
|
||||
|
||||
squigglyLevel(1),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(0),
|
||||
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,257 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.lang.ecmascript6.JSXHarmonyFileType
|
||||
import com.intellij.lang.javascript.JavaScriptFileType
|
||||
import com.intellij.lang.javascript.TypeScriptFileType
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowJavaScriptTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun testJavaScriptPluginEnabled() {
|
||||
assertTrue(PluginManagerCore.getPlugin(PluginId.getId("JavaScript"))?.isEnabled!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue11() {
|
||||
@Language("JavaScript") val code = """
|
||||
"use strict";
|
||||
|
||||
const _ = require('lodash') || false
|
||||
const moment = require('moment')
|
||||
""".trimIndent()
|
||||
|
||||
myFixture.configureByText(JavaScriptFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue12() {
|
||||
@Language("JavaScript") val code = """
|
||||
"use strict";
|
||||
console.log(a > b)
|
||||
console.log(a == b)
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaScriptFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue21() {
|
||||
|
||||
@Language("JavaScript") val code = "open (\$" + "{f})\n" + "open (\$" + "{f} )"
|
||||
|
||||
myFixture.configureByText(JavaScriptFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue23() {
|
||||
@Language("JavaScript") val code = """
|
||||
"use strict";
|
||||
|
||||
var a;
|
||||
|
||||
if ((a.field_detail && a.is) ||
|
||||
(a.field_detail && a.is) ||
|
||||
(a.field_detail && a.is) ||
|
||||
(a.field_detail && a.is) ||
|
||||
(a.field_detail && a.is) ||
|
||||
(a.field_detail && a.is) ||
|
||||
(a.field_detail && a.is)
|
||||
) ;
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
myFixture.configureByText(JavaScriptFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue38() {
|
||||
@Language("JavaScript") val code = """
|
||||
const element = ( <div> <h1>Hello, world!</h1> </div> );
|
||||
""".trimIndent()
|
||||
|
||||
myFixture.configureByText(JSXHarmonyFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.filterNot { it == null }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `for somehow, it just don't work "testIssue39"`() {
|
||||
@Language("JavaScript") val code = """
|
||||
const html = '<div><div><div>Hello</div></div></div>'
|
||||
""".trimIndent()
|
||||
|
||||
myFixture.configureByText(JavaScriptFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.filterNot { it == null }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(0),
|
||||
angleLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue31() {
|
||||
@Language("JavaScript") val code = """
|
||||
"use strict";
|
||||
const f = () => {}
|
||||
const a = [1,2,3]
|
||||
const s = `<ololo>`
|
||||
""".trimIndent()
|
||||
|
||||
myFixture.configureByText(TypeScriptFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.filterNot { it == null }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(0),
|
||||
squareLevel(0),
|
||||
squareLevel(0)
|
||||
//, angleLevel(0)
|
||||
//, angleLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue427() {
|
||||
@Language("TypeScript") val code = """let example: Array<Map<string,string>>;""".trimIndent()
|
||||
|
||||
myFixture.configureByText(TypeScriptFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.filterNot { it == null }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@@ -1,301 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowJavaTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
override fun tearDown() {
|
||||
super.tearDown()
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isRainbowEnabled = true
|
||||
rainbowSettings.isEnableRainbowAngleBrackets = true
|
||||
rainbowSettings.isEnableRainbowRoundBrackets = true
|
||||
rainbowSettings.isEnableRainbowSquareBrackets = true
|
||||
rainbowSettings.isEnableRainbowSquigglyBrackets = true
|
||||
rainbowSettings.isDoNOTRainbowifyBracketsWithoutContent = false
|
||||
rainbowSettings.cycleCountOnAllBrackets = false
|
||||
rainbowSettings.applyColorsOfRoundForAllBrackets = false
|
||||
rainbowSettings.languageBlacklist = setOf()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForJava() {
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
squigglyLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(2),
|
||||
roundLevel(2),
|
||||
roundLevel(1),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDisableRainbowForJava() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isRainbowEnabled = false
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDisableRainbowAngleBracketsForJava() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isEnableRainbowAngleBrackets = false
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
squigglyLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(2),
|
||||
roundLevel(2),
|
||||
roundLevel(1),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDisableRainbowRoundBracketsForJava() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isEnableRainbowRoundBrackets = false
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDisableRainbowSquigglyBracketsForJava() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isEnableRainbowSquigglyBrackets = false
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(2),
|
||||
roundLevel(2),
|
||||
roundLevel(1),
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoNOTRainbowifyBracketsWithoutContentForJava() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isDoNOTRainbowifyBracketsWithoutContent = true
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(1),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoNOTRainbowifyBracketsWhenJavaInBlacklist() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isDoNOTRainbowifyBracketsWithoutContent = true
|
||||
rainbowSettings.languageBlacklist = setOf("java")
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.size
|
||||
.shouldBe(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIssue391() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.cycleCountOnAllBrackets = true
|
||||
rainbowSettings.applyColorsOfRoundForAllBrackets = true
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),//{
|
||||
|
||||
roundLevel(1),//(
|
||||
roundLevel(1),//)
|
||||
|
||||
roundLevel(1),//{
|
||||
|
||||
roundLevel(2),
|
||||
roundLevel(2),
|
||||
roundLevel(2),
|
||||
roundLevel(3),
|
||||
roundLevel(4),
|
||||
roundLevel(4),
|
||||
roundLevel(3),
|
||||
roundLevel(2),
|
||||
|
||||
roundLevel(1),//}
|
||||
|
||||
roundLevel(0)//}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,200 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowKotlinTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun testRainbowForKotlin() {
|
||||
@Language("kotlin") val code =
|
||||
"""
|
||||
fun <T> filter(l: List<T>, f: (T) -> Boolean): MutableList<T> {
|
||||
val res = mutableListOf<T>()
|
||||
l.forEach { if (f(it)) { res += it } }
|
||||
return res
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
roundLevel(0),
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(0),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
squigglyLevel(0),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
|
||||
roundLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(2),
|
||||
squigglyLevel(2),
|
||||
|
||||
squigglyLevel(1),
|
||||
|
||||
|
||||
squigglyLevel(0)
|
||||
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowArrowForKotlin() {
|
||||
@Language("kotlin") val code =
|
||||
"""
|
||||
val a: (Int) -> Unit = { aa ->
|
||||
val b: (Int) -> Unit = { bb ->
|
||||
val c: (Int) -> Unit = { cc ->
|
||||
val d: (Int) -> Unit = { dd ->
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting
|
||||
.filter { brackets.contains(it.text.toChar()) || it.text.contains("->") }
|
||||
.filter { it?.forcedTextAttributesKey?.defaultAttributes != null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(0),
|
||||
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(1),
|
||||
|
||||
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(2),
|
||||
squigglyLevel(2),
|
||||
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(3),
|
||||
squigglyLevel(3),
|
||||
|
||||
|
||||
squigglyLevel(3),
|
||||
|
||||
squigglyLevel(2),
|
||||
|
||||
|
||||
squigglyLevel(1),
|
||||
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ForSomeHowTheTestNotPassed "testRainbowLabelForKotlin"`() {
|
||||
@Language("kotlin") val code =
|
||||
"""
|
||||
class AA {
|
||||
fun aa() {
|
||||
arrayOf(1, 2, 3).forEach {
|
||||
it.let dd@{
|
||||
if (it > 0) a@{
|
||||
return@dd
|
||||
}
|
||||
}
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
|
||||
doHighlighting
|
||||
.filter { it.forcedTextAttributes != null && it.text.contains("@") }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
squigglyLevel(3),
|
||||
squigglyLevel(4),
|
||||
squigglyLevel(3),
|
||||
squigglyLevel(2)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKotlinFunctionLiteralBracesAndArrow() {
|
||||
@Language("kotlin") val code =
|
||||
"""
|
||||
val a :Int = 1
|
||||
|
||||
fun t() {
|
||||
a?.let {
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
|
||||
doHighlighting
|
||||
.filter { brackets.contains(it.text.toChar()) }
|
||||
.filter { it?.forcedTextAttributesKey?.defaultAttributes != null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(0),
|
||||
//squigglyLevel(1),
|
||||
//squigglyLevel(1),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.jetbrains.php.lang.PhpFileType
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowPHPTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun testRainbowForPHP() {
|
||||
val code =
|
||||
"""
|
||||
<?php
|
||||
|
||||
function padZero(string data): string
|
||||
{
|
||||
remainder = Binary::safeStrlen(data) % 8;
|
||||
if (remainder > 0) {
|
||||
data = str_repeat(self::NULL_BYTE, 8 - remainder);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
?>
|
||||
"""
|
||||
myFixture.configureByText(PhpFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(0),
|
||||
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
|
||||
squigglyLevel(1),
|
||||
roundLevel(2),
|
||||
roundLevel(2),
|
||||
squigglyLevel(1),
|
||||
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,161 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.jetbrains.plugins.ruby.ruby.lang.RubyFileType
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowRubyTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun testRubyPluginEnabled() {
|
||||
assertTrue(PluginManagerCore.getPlugin(PluginId.getId("org.jetbrains.plugins.ruby"))?.isEnabled!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForIssue53Part0() {
|
||||
val code =
|
||||
"""
|
||||
class Test
|
||||
a = (1 + 2 + (3))
|
||||
end
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(RubyFileType.RUBY, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(1),
|
||||
roundLevel(1),
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForIssue53Part1() {
|
||||
val code =
|
||||
"""
|
||||
foobar(p1: "", p2: false, p3: 1)
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(RubyFileType.RUBY, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
roundLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForIssue53Part2() {
|
||||
val code =
|
||||
"""
|
||||
#noinspection RubyDeadCode,RubyResolve
|
||||
def foo
|
||||
some_function(true, { :before => {a: 1},
|
||||
:after => {b: 2} })
|
||||
call_block { do_something }
|
||||
end
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(RubyFileType.RUBY, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting
|
||||
.filter { brackets.contains(it.text.toChar()) }
|
||||
.filterNot { it?.forcedTextAttributesKey?.defaultAttributes == null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
roundLevel(0),
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForIssue53Part3() {
|
||||
val code =
|
||||
"""
|
||||
#noinspection RubyResolve
|
||||
def bar
|
||||
case @var
|
||||
when 1
|
||||
print [1..42]
|
||||
else
|
||||
print [1...42]
|
||||
end
|
||||
end
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(RubyFileType.RUBY, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting
|
||||
.filter { brackets.contains(it.text.toChar()) }
|
||||
.filterNot { it?.forcedTextAttributesKey?.defaultAttributes == null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
squareLevel(0),
|
||||
squareLevel(0),
|
||||
squareLevel(0),
|
||||
squareLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForIssue53Part4() {
|
||||
val code =
|
||||
"""
|
||||
if true
|
||||
A = [1, [2, [3] ] ]
|
||||
end
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(RubyFileType.RUBY, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting
|
||||
.filter { brackets.contains(it.text.toChar()) }
|
||||
.filterNot { it?.forcedTextAttributesKey?.defaultAttributes == null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
squareLevel(0),
|
||||
squareLevel(1),
|
||||
squareLevel(2),
|
||||
squareLevel(2),
|
||||
squareLevel(1),
|
||||
squareLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,103 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.plugins.scala.ScalaFileType
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowScalaTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
override fun tearDown() {
|
||||
super.tearDown()
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isRainbowEnabled = true
|
||||
rainbowSettings.isEnableRainbowAngleBrackets = true
|
||||
rainbowSettings.isEnableRainbowRoundBrackets = true
|
||||
rainbowSettings.isEnableRainbowSquareBrackets = true
|
||||
rainbowSettings.isEnableRainbowSquigglyBrackets = true
|
||||
rainbowSettings.isDoNOTRainbowifyBracketsWithoutContent = false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForScala() {
|
||||
@Language("Scala") val code =
|
||||
"""
|
||||
import scala.annotation.tailrec
|
||||
|
||||
@tailrec
|
||||
private def loop[V](key: String): V = {
|
||||
key match {
|
||||
case _ => loop[V](key)
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(ScalaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.filter { it?.forcedTextAttributesKey != null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
squareLevel(0),
|
||||
squareLevel(0),
|
||||
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(1),
|
||||
squareLevel(0),
|
||||
squareLevel(0),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDisableRainbowSquareBracketsForScala() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isEnableRainbowSquareBrackets = false
|
||||
@Language("Scala") val code =
|
||||
"""
|
||||
import scala.annotation.tailrec
|
||||
|
||||
@tailrec
|
||||
private def loop[V](key: String): V = {
|
||||
key match {
|
||||
case _ => loop[V](key)
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(ScalaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.filter { it?.forcedTextAttributesKey != null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
|
||||
squigglyLevel(0),
|
||||
squigglyLevel(1),
|
||||
roundLevel(0),
|
||||
roundLevel(0),
|
||||
squigglyLevel(1),
|
||||
squigglyLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,153 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.ide.highlighter.XmlFileType
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Test
|
||||
|
||||
class RainbowXMLTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun `disabled for non-determinist results of testRainbowTagNameForXML`() {
|
||||
@Language("XML") val code =
|
||||
"""
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE note SYSTEM>
|
||||
<idea-plugin>
|
||||
<name>Rainbow Brackets</name>
|
||||
<description>
|
||||
<p>Supported languages:</p>
|
||||
<p>Java, Scala, Clojure, Kotlin, Python, Haskell, Agda, Rust, JavaScript, TypeScript, Erlang, Go, Groovy, Ruby, Elixir, ObjectiveC, PHP, C#, HTML, XML, SQL, Apex language ...</p>
|
||||
<br/>
|
||||
</description>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.rainbowifyTagNameInXML = true
|
||||
myFixture.configureByText(XmlFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),//idea-plugin
|
||||
angleLevel(0),
|
||||
|
||||
angleLevel(1),
|
||||
angleLevel(1),//name
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(1),//name
|
||||
angleLevel(1),
|
||||
|
||||
angleLevel(1),
|
||||
angleLevel(1),//description
|
||||
angleLevel(1),
|
||||
|
||||
angleLevel(2),
|
||||
angleLevel(2),//p
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),//p
|
||||
angleLevel(2),
|
||||
|
||||
angleLevel(2),
|
||||
angleLevel(2),//p
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),//p
|
||||
angleLevel(2),
|
||||
|
||||
angleLevel(2),
|
||||
angleLevel(2),//br
|
||||
angleLevel(2),
|
||||
|
||||
angleLevel(1),
|
||||
angleLevel(1),//description
|
||||
angleLevel(1),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),//idea-plugin
|
||||
angleLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRainbowForXML() {
|
||||
@Language("XML") val code =
|
||||
"""
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE note SYSTEM>
|
||||
<idea-plugin>
|
||||
<name>Rainbow Brackets</name>
|
||||
<description>
|
||||
<p>Supported languages:</p>
|
||||
<p>Java, Scala, Clojure, Kotlin, Python, Haskell, Agda, Rust, JavaScript, TypeScript, Erlang, Go, Groovy, Ruby, Elixir, ObjectiveC, PHP, C#, HTML, XML, SQL, Apex language ...</p>
|
||||
<br/>
|
||||
</description>
|
||||
</idea-plugin>
|
||||
""".trimIndent()
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.rainbowifyTagNameInXML = false
|
||||
myFixture.configureByText(XmlFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
doHighlighting
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.shouldBe(
|
||||
arrayOf(
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0),
|
||||
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
|
||||
angleLevel(2),
|
||||
angleLevel(2),
|
||||
|
||||
angleLevel(1),
|
||||
angleLevel(1),
|
||||
|
||||
angleLevel(0),
|
||||
angleLevel(0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Test
|
||||
|
||||
class RandomColorGenTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
@Test
|
||||
fun testRandomColorGenWorks() {
|
||||
val rainbowSettings = RainbowSettings.instance
|
||||
rainbowSettings.isRainbowEnabled = true
|
||||
rainbowSettings.useColorGenerator = true
|
||||
|
||||
@Language("Java") val code =
|
||||
"""
|
||||
public class Test<T> {
|
||||
public Boolean test() {
|
||||
return "true".equals("false") || "false".equals("true".concat("false".length() + "*"));
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, code)
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
val doHighlighting = myFixture.doHighlighting()
|
||||
assertFalse(doHighlighting.isEmpty())
|
||||
val highlightSize = doHighlighting.filter { brackets.contains(it.text.toChar()) }
|
||||
.filter { it.forcedTextAttributesKey.defaultAttributes.foregroundColor != null }
|
||||
.map { it.forcedTextAttributesKey.defaultAttributes.foregroundColor }
|
||||
.toTypedArray()
|
||||
.size
|
||||
assert(highlightSize == 16)
|
||||
}
|
||||
|
||||
}
|
@@ -1,11 +1,7 @@
|
||||
plugins {
|
||||
id("org.jetbrains.intellij")
|
||||
}
|
||||
|
||||
intellij {
|
||||
type.set("RD")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":idea"))
|
||||
implementation(rootProject)
|
||||
}
|
||||
|
@@ -0,0 +1,13 @@
|
||||
package com.chylex.intellij.coloredbrackets.provider
|
||||
|
||||
import com.intellij.lang.BracePair
|
||||
import com.jetbrains.rider.languages.fileTypes.csharp.kotoparser.lexer.CSharpTokenType
|
||||
|
||||
class CSharpBracePairProvider : BracePairProvider {
|
||||
override fun pairs(): List<BracePair> = listOf(
|
||||
BracePair(CSharpTokenType.LPARENTH, CSharpTokenType.RPARENTH, false),
|
||||
BracePair(CSharpTokenType.LBRACE, CSharpTokenType.RBRACE, false),
|
||||
BracePair(CSharpTokenType.LBRACKET, CSharpTokenType.RBRACKET, false),
|
||||
BracePair(CSharpTokenType.LT, CSharpTokenType.GT, false),
|
||||
)
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
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),
|
||||
)
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package com.chylex.intellij.coloredbrackets.visitor
|
||||
|
||||
import com.chylex.intellij.coloredbrackets.settings.RainbowSettings
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.jetbrains.rider.languages.fileTypes.csharp.kotoparser.lexer.CSharpTokenType
|
||||
import com.jetbrains.rider.languages.fileTypes.csharp.psi.CSharpDummyNode
|
||||
|
||||
class CSharpRainbowVisitor : ReSharperRainbowVisitor("C#") {
|
||||
|
||||
override fun suitableForFile(file: PsiFile): Boolean {
|
||||
return super.suitableForFile(file) && RainbowSettings.instance.isEnableRainbowAngleBrackets
|
||||
}
|
||||
|
||||
override fun isAllowedElementType(type: IElementType): Boolean {
|
||||
return type == CSharpTokenType.LPARENTH || type == CSharpTokenType.RPARENTH
|
||||
}
|
||||
|
||||
override fun PsiElement.isDummyNode(): Boolean {
|
||||
return this is CSharpDummyNode
|
||||
}
|
||||
|
||||
override fun clone(): HighlightVisitor = CSharpRainbowVisitor()
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
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
|
||||
}
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
package com.chylex.intellij.coloredbrackets.visitor
|
||||
|
||||
import com.chylex.intellij.coloredbrackets.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,13 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.provider
|
||||
|
||||
import com.intellij.lang.BracePair
|
||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.kotoparser.lexer.CSharpTokenType
|
||||
|
||||
class CSharpBracePairProvider : BracePairProvider {
|
||||
override fun pairs(): List<BracePair> = listOf(
|
||||
BracePair(CSharpTokenType.LPARENTH, CSharpTokenType.RPARENTH, false),
|
||||
BracePair(CSharpTokenType.LBRACE, CSharpTokenType.RBRACE, false),
|
||||
BracePair(CSharpTokenType.LBRACKET, CSharpTokenType.RBRACKET, false),
|
||||
BracePair(CSharpTokenType.LT, CSharpTokenType.GT, false),
|
||||
)
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
package com.github.izhangzhihao.rainbow.brackets.visitor
|
||||
|
||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
||||
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.jetbrains.rider.ideaInterop.fileTypes.csharp.kotoparser.lexer.CSharpTokenType
|
||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.psi.CSharpDummyNode
|
||||
|
||||
class CSharpRainbowVisitor : RainbowHighlightVisitor() {
|
||||
|
||||
override fun suitableForFile(file: PsiFile)
|
||||
: Boolean = super.suitableForFile(file) &&
|
||||
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
||||
(file.language.id == "C#" ||
|
||||
file.viewProvider.allFiles.any { it.language.id == "C#" }
|
||||
)
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
rider/src/main/resources/META-INF/cpp-rider-brackets.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<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>
|
5
rider/src/main/resources/META-INF/csharp-annotator.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<annotator language="C#" implementationClass="com.chylex.intellij.coloredbrackets.annotator.RainbowAnnotator" />
|
||||
</extensions>
|
||||
</idea-plugin>
|
@@ -1,10 +1,10 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.chylex.intellij.rainbowbrackets">
|
||||
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||
<bracePairProvider language="C#"
|
||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.CSharpBracePairProvider"/>
|
||||
implementationClass="com.chylex.intellij.coloredbrackets.provider.CSharpBracePairProvider" />
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.CSharpRainbowVisitor"/>
|
||||
<highlightVisitor implementation="com.chylex.intellij.coloredbrackets.visitor.CSharpRainbowVisitor" />
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 22 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="120.1" height="130.2" x="0" style="enable-background:new 0 0 120.1 130.2" y="0" version="1.1" viewBox="0 0 120.1 130.2" xml:space="preserve"><g><linearGradient id="XMLID_2_" x1="31.841" x2="110.24" y1="120.558" y2="73.24" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#fcee39"/><stop offset="1" style="stop-color:#f37b3d"/></linearGradient><path id="XMLID_3041_" d="M118.6,71.8c0.9-0.8,1.4-1.9,1.5-3.2c0.1-2.6-1.8-4.7-4.4-4.9 c-1.2-0.1-2.4,0.4-3.3,1.1l0,0l-83.8,45.9c-1.9,0.8-3.6,2.2-4.7,4.1c-2.9,4.8-1.3,11,3.6,13.9c3.4,2,7.5,1.8,10.7-0.2l0,0l0,0 c0.2-0.2,0.5-0.3,0.7-0.5l78-54.8C117.3,72.9,118.4,72.1,118.6,71.8L118.6,71.8L118.6,71.8z" style="fill:url(#XMLID_2_)"/><linearGradient id="XMLID_3_" x1="48.361" x2="119.918" y1="6.908" y2="69.555" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#ef5a6b"/><stop offset=".57" style="stop-color:#f26f4e"/><stop offset="1" style="stop-color:#f37b3d"/></linearGradient><path id="XMLID_3049_" d="M118.8,65.1L118.8,65.1L55,2.5C53.6,1,51.6,0,49.3,0 c-4.3,0-7.7,3.5-7.7,7.7v0c0,2.1,0.8,3.9,2.1,5.3l0,0l0,0c0.4,0.4,0.8,0.7,1.2,1l67.4,57.7l0,0c0.8,0.7,1.8,1.2,3,1.3 c2.6,0.1,4.7-1.8,4.9-4.4C120.2,67.3,119.7,66,118.8,65.1z" style="fill:url(#XMLID_3_)"/><linearGradient id="XMLID_4_" x1="52.947" x2="10.538" y1="63.641" y2="37.156" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#7c59a4"/><stop offset=".385" style="stop-color:#af4c92"/><stop offset=".765" style="stop-color:#dc4183"/><stop offset=".957" style="stop-color:#ed3d7d"/></linearGradient><path id="XMLID_3042_" d="M57.1,59.5C57,59.5,17.7,28.5,16.9,28l0,0l0,0c-0.6-0.3-1.2-0.6-1.8-0.9 c-5.8-2.2-12.2,0.8-14.4,6.6c-1.9,5.1,0.2,10.7,4.6,13.4l0,0l0,0C6,47.5,6.6,47.8,7.3,48c0.4,0.2,45.4,18.8,45.4,18.8l0,0 c1.8,0.8,3.9,0.3,5.1-1.2C59.3,63.7,59,61,57.1,59.5z" style="fill:url(#XMLID_4_)"/><linearGradient id="XMLID_5_" x1="52.174" x2="10.771" y1="3.702" y2="37.897" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#ef5a6b"/><stop offset=".364" style="stop-color:#ee4e72"/><stop offset="1" style="stop-color:#ed3d7d"/></linearGradient><path id="XMLID_3057_" d="M49.3,0c-1.7,0-3.3,0.6-4.6,1.5L4.9,28.3c-0.1,0.1-0.2,0.1-0.2,0.2l-0.1,0 l0,0c-1.7,1.2-3.1,3-3.9,5.1C-1.5,39.4,1.5,45.9,7.3,48c3.6,1.4,7.5,0.7,10.4-1.4l0,0l0,0c0.7-0.5,1.3-1,1.8-1.6l34.6-31.2l0,0 c1.8-1.4,3-3.6,3-6.1v0C57.1,3.5,53.6,0,49.3,0z" style="fill:url(#XMLID_5_)"/><g id="XMLID_3008_"><rect id="XMLID_3033_" width="51" height="51" x="34.6" y="37.4" style="fill:#000"/><rect id="XMLID_3032_" width="19.1" height="3.2" x="39" y="78.8" style="fill:#fff"/><g id="XMLID_3009_"><path id="XMLID_3030_" d="M38.8,50.8l1.5-1.4c0.4,0.5,0.8,0.8,1.3,0.8c0.6,0,0.9-0.4,0.9-1.2l0-5.3l2.3,0 l0,5.3c0,1-0.3,1.8-0.8,2.3c-0.5,0.5-1.3,0.8-2.3,0.8C40.2,52.2,39.4,51.6,38.8,50.8z" style="fill:#fff"/><path id="XMLID_3028_" d="M45.3,43.8l6.7,0v1.9l-4.4,0V47l4,0l0,1.8l-4,0l0,1.3l4.5,0l0,2l-6.7,0 L45.3,43.8z" style="fill:#fff"/><path id="XMLID_3026_" d="M55,45.8l-2.5,0l0-2l7.3,0l0,2l-2.5,0l0,6.3l-2.3,0L55,45.8z" style="fill:#fff"/><path id="XMLID_3022_" d="M39,54l4.3,0c1,0,1.8,0.3,2.3,0.7c0.3,0.3,0.5,0.8,0.5,1.4v0 c0,1-0.5,1.5-1.3,1.9c1,0.3,1.6,0.9,1.6,2v0c0,1.4-1.2,2.3-3.1,2.3l-4.3,0L39,54z M43.8,56.6c0-0.5-0.4-0.7-1-0.7l-1.5,0l0,1.5 l1.4,0C43.4,57.3,43.8,57.1,43.8,56.6L43.8,56.6z M43,59l-1.8,0l0,1.5H43c0.7,0,1.1-0.3,1.1-0.8v0C44.1,59.2,43.7,59,43,59z" style="fill:#fff"/><path id="XMLID_3019_" d="M46.8,54l3.9,0c1.3,0,2.1,0.3,2.7,0.9c0.5,0.5,0.7,1.1,0.7,1.9v0 c0,1.3-0.7,2.1-1.7,2.6l2,2.9l-2.6,0l-1.7-2.5h-1l0,2.5l-2.3,0L46.8,54z M50.6,58c0.8,0,1.2-0.4,1.2-1v0c0-0.7-0.5-1-1.2-1 l-1.5,0v2H50.6z" style="fill:#fff"/><path id="XMLID_3016_" d="M56.8,54l2.2,0l3.5,8.4l-2.5,0l-0.6-1.5l-3.2,0l-0.6,1.5l-2.4,0L56.8,54z M58.8,59l-0.9-2.3L57,59L58.8,59z" style="fill:#fff"/><path id="XMLID_3014_" d="M62.8,54l2.3,0l0,8.3l-2.3,0L62.8,54z" style="fill:#fff"/><path id="XMLID_3012_" d="M65.7,54l2.1,0l3.4,4.4l0-4.4l2.3,0l0,8.3l-2,0L68,57.8l0,4.6l-2.3,0L65.7,54z" style="fill:#fff"/><path id="XMLID_3010_" d="M73.7,61.1l1.3-1.5c0.8,0.7,1.7,1,2.7,1c0.6,0,1-0.2,1-0.6v0 c0-0.4-0.3-0.5-1.4-0.8c-1.8-0.4-3.1-0.9-3.1-2.6v0c0-1.5,1.2-2.7,3.2-2.7c1.4,0,2.5,0.4,3.4,1.1l-1.2,1.6 c-0.8-0.5-1.6-0.8-2.3-0.8c-0.6,0-0.8,0.2-0.8,0.5v0c0,0.4,0.3,0.5,1.4,0.8c1.9,0.4,3.1,1,3.1,2.6v0c0,1.7-1.3,2.7-3.4,2.7 C76.1,62.5,74.7,62,73.7,61.1z" style="fill:#fff"/></g></g></g></svg>
|
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 29 KiB |