Compare commits
1 Commits
2977a08009
...
201b6e1f3a
Author | SHA1 | Date | |
---|---|---|---|
201b6e1f3a |
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.
|
|
69
.github/CONTRIBUTING.md
vendored
@ -1,69 +0,0 @@
|
|||||||
## Contribute
|
|
||||||
|
|
||||||
NOTE: To view the PSI tree and explore the internal PSI structure of source code, you need to set up your IDE by following [this](https://www.jetbrains.com/help/idea/psi-viewer.html).
|
|
||||||
For the Rider IDE, please follow: [this](https://rider-support.jetbrains.com/hc/en-us/articles/207327910-How-to-run-JetBrains-Rider-in-Internal-Mode)
|
|
||||||
|
|
||||||
For small changes, [Gitpod](https://gitpod.io/#https://github.com/izhangzhihao/intellij-rainbow-brackets) is recommended. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/izhangzhihao/intellij-rainbow-brackets)
|
|
||||||
|
|
||||||
* `gradle test`
|
|
||||||
* `gradle runIde`
|
|
||||||
* `gradle buildPlugin`
|
|
||||||
|
|
||||||
## Support Us
|
|
||||||
|
|
||||||
You can support us by the following actions:
|
|
||||||
|
|
||||||
* Star this project
|
|
||||||
* Share this plugin with your friends
|
|
||||||
* Rate this plugin on [JetBrains plugin repository](https://plugins.jetbrains.com/plugin/10080-rainbow-brackets)
|
|
||||||
* Make pull requests
|
|
||||||
* Report bugs
|
|
||||||
* Tell us your ideas
|
|
||||||
* Become a sponsor by donating on [Open Collective](https://opencollective.com/intellij-rainbow-brackets)
|
|
||||||
* Become a sponsor by donating with AliPay or WeChatPay
|
|
||||||
* Don't want to use AliPay's mobile App? If you could read Chinese, please use [the official website](https://shenghuo.alipay.com/send/payment/fill.htm) to transfer your donation to my Alipay account(izhangzhihao@hotmail.com). Otherwise, you can try [the English version of Alipay](https://global.alipay.com/) to transfer your donation.
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th width="33%">Open Collective</th>
|
|
||||||
<th width="33%">AliPay</th>
|
|
||||||
<th width="33%">WeChatPay</th>
|
|
||||||
</tr>
|
|
||||||
<tr></tr>
|
|
||||||
<tr align="center">
|
|
||||||
<td>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets" target="_blank">
|
|
||||||
<img src="https://cdn.jsdelivr.net/gh/YiiGuxing/TranslationPlugin@master/images/open-collective.svg" width="171px" alt="OpenCollective">
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><img src="https://user-images.githubusercontent.com/12044174/85197261-77dd5a80-b312-11ea-9630-51caf7d634f2.jpg"></td>
|
|
||||||
<td><img src="https://user-images.githubusercontent.com/12044174/85197263-7b70e180-b312-11ea-917a-35eab2ea08ae.jpg"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## Backers
|
|
||||||
|
|
||||||
Thank you to all our backers! ❤️ [[Become a backer](https://opencollective.com/intellij-rainbow-brackets#backer)]
|
|
||||||
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets#backers" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/backers.svg?width=890"></a>
|
|
||||||
|
|
||||||
## Sponsors
|
|
||||||
|
|
||||||
Support this project by becoming a sponsor! 🌈 Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/intellij-rainbow-brackets#sponsor)]
|
|
||||||
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/0/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/0/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/1/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/1/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/2/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/2/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/3/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/3/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/4/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/4/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/5/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/5/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/6/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/6/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/7/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/7/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/8/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/8/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/9/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/9/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/10/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/10/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/11/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/11/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/12/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/12/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/13/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/13/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/14/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/14/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/15/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/15/avatar.svg"></a>
|
|
2
.github/FUNDING.yml
vendored
@ -1,2 +0,0 @@
|
|||||||
open_collective: intellij-rainbow-brackets
|
|
||||||
custom: https://github.com/izhangzhihao/intellij-rainbow-brackets#support-us
|
|
57
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,57 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: bug?
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Your issue may already be reported!
|
|
||||||
Please search on the [issues](https://github.com/izhangzhihao/intellij-rainbow-brackets/issues) and the [document](https://github.com/izhangzhihao/intellij-rainbow-brackets/blob/2020.3/README.md) before creating one.
|
|
||||||
|
|
||||||
## Please check
|
|
||||||
|
|
||||||
- [ ] I already support this project.
|
|
||||||
- [ ] If you are submitting a feature request, please do consider donating us on [Open Collective](https://opencollective.com/intellij-rainbow-brackets) Or by AliPay/WeChatPay.
|
|
||||||
- [ ] This issue/feature request is not reported before.
|
|
||||||
|
|
||||||
## Your programming languages
|
|
||||||
|
|
||||||
## Expected Behavior
|
|
||||||
* If you're describing a bug, tell us what should happen
|
|
||||||
* If you're suggesting a change/improvement, tell us how it should work
|
|
||||||
|
|
||||||
## Current Behavior
|
|
||||||
* If describing a bug, tell us what happens instead of the expected behavior
|
|
||||||
* If suggesting a change/improvement, explain the difference from current behavior
|
|
||||||
|
|
||||||
## Possible Solution
|
|
||||||
Not obligatory, but suggest a fix/reason for the bug, or ideas how to implement the addition or change.
|
|
||||||
Or what have you tried to resolve this issue.
|
|
||||||
|
|
||||||
## Code snippet for reproduce (for bugs)
|
|
||||||
Please provide code snippet for reproduce bugs.
|
|
||||||
|
|
||||||
## Your Environment
|
|
||||||
|
|
||||||
* Plugin version:
|
|
||||||
* IDE & Operating System version, comment your env as below(go to "About IntelliJ IDEA" -> click the "copy" icon):
|
|
||||||
* NOTE: If you are going to report a bug but WITHOUT your env information, your issue might be closed directly.
|
|
||||||
|
|
||||||
```
|
|
||||||
IntelliJ IDEA 2021.2 (Ultimate Edition)
|
|
||||||
Build #IU-212.4746.92, built on July 27, 2021
|
|
||||||
Licensed to IntelliJ Rainbow Brackets / Zhang Zhihao
|
|
||||||
Subscription is active until February 3, 2022.
|
|
||||||
For non-commercial open source development only.
|
|
||||||
Runtime version: 11.0.11+9-b1504.13 x86_64
|
|
||||||
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
|
|
||||||
macOS 11.4
|
|
||||||
GC: G1 Young Generation, G1 Old Generation
|
|
||||||
Memory: 4096M
|
|
||||||
Cores: 16
|
|
||||||
Registry: ide.tooltip.initialDelay=900, ide.balloon.shadow.size=0, scala.erase.compiler.process.jdk.once=false
|
|
||||||
Non-Bundled Plugins: com.intellij.properties.bundle.editor (212.4746.57), com.markskelton.one-dark-theme (5.3.0), lermitage.intellij.extra.icons (1.59.0.203), org.nik.presentation-assistant (1.0.9), kotest-plugin-intellij (1.1.36-IC-2021.1), Pythonid (212.4746.96), org.intellij.scala (2021.2.15), izhangzhihao.rainbow.brackets (6.19), com.intellij.bigdatatools (212.4037.55)
|
|
||||||
Kotlin: 212-1.5.10-release-IJ4746.92
|
|
||||||
```
|
|
24
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: feature request
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Please [support us](https://github.com/izhangzhihao/intellij-rainbow-brackets#support-us) before creating a feature request, thanks for your support 😁**
|
|
||||||
|
|
||||||
## Please check
|
|
||||||
|
|
||||||
- [ ] I already support this project.
|
|
||||||
- [ ] If you are submitting a feature request, please do consider donating us on [Open Collective](https://opencollective.com/intellij-rainbow-brackets) Or by AliPay/WeChatPay.
|
|
||||||
- [ ] This issue/feature request is not reported before.
|
|
||||||
|
|
||||||
## Your programming languages
|
|
||||||
|
|
||||||
## Expected Behavior
|
|
||||||
* tell us how it will works
|
|
||||||
|
|
||||||
## Current Behavior
|
|
||||||
* explain the difference from current behavior
|
|
13
.github/opencollective.yml
vendored
@ -1,13 +0,0 @@
|
|||||||
collective: intellij-rainbow-brackets
|
|
||||||
tiers:
|
|
||||||
- tiers: "*"
|
|
||||||
labels: ["backer"]
|
|
||||||
message: "Hey <author> , thanks for supporting us on Open Collective :heart::heart::heart: We'll give a special attention to this issue!"
|
|
||||||
invitation: |
|
|
||||||
Hey <author> :wave:,
|
|
||||||
|
|
||||||
Thank you for opening an issue/feature request. We will get back to you as soon as we can.
|
|
||||||
Also, check out our <link> and consider backing us - every little helps!
|
|
||||||
|
|
||||||
PS.: We offer `priority` support for all backers. Don't forget to
|
|
||||||
add `priority` label when you start backing us :smile:
|
|
75
.github/workflows/build.yml
vendored
@ -1,75 +0,0 @@
|
|||||||
name: Build
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '2020.3'
|
|
||||||
pull_request:
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Setup Java 11 environment for the next steps
|
|
||||||
- name: Setup Java
|
|
||||||
uses: actions/setup-java@v2
|
|
||||||
with:
|
|
||||||
distribution: 'adopt'
|
|
||||||
java-version: 11
|
|
||||||
|
|
||||||
# Check out current repository
|
|
||||||
- name: Fetch Sources
|
|
||||||
uses: actions/checkout@v2.3.4
|
|
||||||
|
|
||||||
# Cache Gradle dependencies
|
|
||||||
- name: Setup Gradle Dependencies Cache
|
|
||||||
uses: actions/cache@v2.1.6
|
|
||||||
with:
|
|
||||||
path: ~/.gradle/caches
|
|
||||||
key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/*.gradle', '**/*.gradle.kts') }}
|
|
||||||
|
|
||||||
# Cache Gradle Wrapper
|
|
||||||
- name: Setup Gradle Wrapper Cache
|
|
||||||
uses: actions/cache@v2.1.6
|
|
||||||
with:
|
|
||||||
path: ~/.gradle/wrapper
|
|
||||||
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
|
|
||||||
|
|
||||||
# Run detekt, ktlint and tests
|
|
||||||
- name: Run Linters and Test
|
|
||||||
run: ./gradlew check
|
|
||||||
|
|
||||||
# Run verifyPlugin Gradle task
|
|
||||||
- name: Verify Plugin
|
|
||||||
run: ./gradlew verifyPlugin
|
|
||||||
|
|
||||||
# Set environment variables
|
|
||||||
- name: Export Properties
|
|
||||||
id: properties
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
PROPERTIES="$(./gradlew properties --console=plain -q)"
|
|
||||||
IDE_VERSIONS="$(echo "$PROPERTIES" | grep "^pluginVerifierIdeVersions:" | base64)"
|
|
||||||
VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
|
|
||||||
NAME="intellij-rainbow-brackets"
|
|
||||||
ARTIFACT="${NAME}-${VERSION}.zip"
|
|
||||||
|
|
||||||
echo "::set-output name=ideVersions::$IDE_VERSIONS"
|
|
||||||
echo "::set-output name=pluginVerifierHomeDir::~/.pluginVerifier"
|
|
||||||
echo "::set-output name=artifact::$ARTIFACT"
|
|
||||||
|
|
||||||
# Cache Plugin Verifier IDEs
|
|
||||||
- name: Setup Plugin Verifier IDEs Cache
|
|
||||||
uses: actions/cache@v2.1.6
|
|
||||||
with:
|
|
||||||
path: ${{ steps.properties.outputs.pluginVerifierHomeDir }}/ides
|
|
||||||
key: ${{ runner.os }}-plugin-verifier-${{ steps.properties.outputs.ideVersions }}
|
|
||||||
|
|
||||||
# Run IntelliJ Plugin Verifier action using GitHub Action
|
|
||||||
- name: Verify Plugin
|
|
||||||
run: ./gradlew runPluginVerifier -Pplugin.verifier.home.dir=${{ steps.properties.outputs.pluginVerifierHomeDir }}
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v2.2.3
|
|
||||||
with:
|
|
||||||
name: UnZipMe
|
|
||||||
path: ./build/distributions/${{ steps.properties.outputs.artifact }}
|
|
27
.github/workflows/label-and-close-issue.yml
vendored
@ -1,27 +0,0 @@
|
|||||||
name: "Label and close wontfix issues"
|
|
||||||
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [opened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
Label:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: Naturalclar/issue-action@v2.0.2
|
|
||||||
with:
|
|
||||||
title-or-body: "both"
|
|
||||||
parameters: '[ {"keywords": ["RainbowHighlightVisitor.kt:35", "RainbowHighlightVisitor.kt:68", "RainbowHighlightVisitor.analyze"], "labels": ["invalid"]} ]'
|
|
||||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
Close:
|
|
||||||
needs: [Label]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v3.0.14
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
days-before-stale: 0
|
|
||||||
days-before-close: 0
|
|
||||||
stale-issue-message: "This auto generated issue has been automatically marked as wontfix because nothing it's wrong here. If you think there are something really wrong, please reply this issue. Thanks for your cooperation."
|
|
||||||
stale-issue-label: "wontfix"
|
|
||||||
only-labels: "invalid"
|
|
46
.github/workflows/release.yml
vendored
@ -1,46 +0,0 @@
|
|||||||
# GitHub Actions Workflow created for handling the release process based on the draft release prepared
|
|
||||||
# with the Build workflow. Running the publishPlugin task requires the PUBLISH_TOKEN secret provided.
|
|
||||||
|
|
||||||
name: Release
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [prereleased, released]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# Prepare and publish the plugin to the Marketplace repository
|
|
||||||
release:
|
|
||||||
name: Publish Plugin
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Setup Java 11 environment for the next steps
|
|
||||||
- name: Setup Java
|
|
||||||
uses: actions/setup-java@v2
|
|
||||||
with:
|
|
||||||
distribution: "adopt"
|
|
||||||
java-version: 11
|
|
||||||
|
|
||||||
# Check out current repository
|
|
||||||
- name: Fetch Sources
|
|
||||||
uses: actions/checkout@v2.3.4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.release.tag_name }}
|
|
||||||
|
|
||||||
# Cache Gradle dependencies
|
|
||||||
- name: Setup Gradle Dependencies Cache
|
|
||||||
uses: actions/cache@v2.1.6
|
|
||||||
with:
|
|
||||||
path: ~/.gradle/caches
|
|
||||||
key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/*.gradle', '**/*.gradle.kts') }}
|
|
||||||
|
|
||||||
# Cache Gradle Wrapper
|
|
||||||
- name: Setup Gradle Wrapper Cache
|
|
||||||
uses: actions/cache@v2.1.6
|
|
||||||
with:
|
|
||||||
path: ~/.gradle/wrapper
|
|
||||||
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
|
|
||||||
|
|
||||||
# Publish the plugin to the Marketplace
|
|
||||||
- name: Publish Plugin
|
|
||||||
env:
|
|
||||||
token: ${{ secrets.PUBLISH_TOKEN }}
|
|
||||||
run: ./gradlew publishPlugin
|
|
19
.github/workflows/stale.yml
vendored
@ -1,19 +0,0 @@
|
|||||||
name: 'Stale handler'
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stale:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@main
|
|
||||||
id: stale
|
|
||||||
with:
|
|
||||||
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'
|
|
||||||
days-before-stale: 30
|
|
||||||
days-before-close: 5
|
|
||||||
only-labels: 'PR welcome'
|
|
||||||
- name: Print outputs
|
|
||||||
run: echo ${{ join(steps.stale.outputs.*, ',') }}
|
|
13
.gitignore
vendored
@ -1,10 +1,5 @@
|
|||||||
/.idea/*
|
/.idea/*
|
||||||
!/.idea/icon.png
|
!/.idea/runConfigurations
|
||||||
!/.idea/icon_dark.png
|
|
||||||
!/.idea/vcs.xml
|
/.gradle/
|
||||||
.sandbox/
|
/build/
|
||||||
.gradle/
|
|
||||||
build/
|
|
||||||
*.iml
|
|
||||||
.DS_Store
|
|
||||||
out
|
|
||||||
|
5
.gitpod.Dockerfile
vendored
@ -1,5 +0,0 @@
|
|||||||
FROM gitpod/workspace-full
|
|
||||||
|
|
||||||
USER gitpod
|
|
||||||
|
|
||||||
RUN brew install kotlin
|
|
@ -1,4 +0,0 @@
|
|||||||
image:
|
|
||||||
file: .gitpod.Dockerfile
|
|
||||||
tasks:
|
|
||||||
- init: gradle compileKotlin
|
|
@ -1 +0,0 @@
|
|||||||
11
|
|
15
.mergify.yml
@ -1,15 +0,0 @@
|
|||||||
pull_request_rules:
|
|
||||||
- name: Automatic merge on approval
|
|
||||||
conditions:
|
|
||||||
- "#approved-reviews-by>=1"
|
|
||||||
- status-success=Test
|
|
||||||
actions:
|
|
||||||
merge:
|
|
||||||
method: merge
|
|
||||||
- name: automatically merge dependabot's PRs
|
|
||||||
conditions:
|
|
||||||
- author~=^dependabot(|-preview)\[bot\]$
|
|
||||||
- status-success=Test
|
|
||||||
actions:
|
|
||||||
merge:
|
|
||||||
method: merge
|
|
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>
|
|
298
README.md
@ -1,297 +1,3 @@
|
|||||||
|
# Colored Brackets
|
||||||
|
|
||||||
<div align="center">
|
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.
|
||||||
<a href="https://plugins.jetbrains.com/plugin/10080-rainbow-brackets">
|
|
||||||
<img src="./src/main/resources/META-INF/pluginIcon.svg" width="320" height="320" alt="logo"/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<h1 align="center">Intellij rainbow brackets</h1>
|
|
||||||
<p align="center">🌈Rainbow Brackets for IntelliJ based IDEs/Android Studio/HUAWEI DevEco Studio.</p>
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<!-- <a href="https://actions-badge.atrox.dev/izhangzhihao/intellij-rainbow-brackets/goto?ref=2020.3"><img alt="Build Status" src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fizhangzhihao%2Fintellij-rainbow-brackets%2Fbadge%3Fref%3D2020.3&style=flat-square" /></a> -->
|
|
||||||
<!-- <a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/releases"><img src="https://img.shields.io/github/release/izhangzhihao/intellij-rainbow-brackets.svg?style=flat-square"></a> -->
|
|
||||||
<a href="https://plugins.jetbrains.com/plugin/10080-rainbow-brackets"><img src="https://img.shields.io/jetbrains/plugin/r/stars/10080?style=flat-square"></a>
|
|
||||||
<a href="https://plugins.jetbrains.com/embeddable/install/10080"><img src="https://img.shields.io/jetbrains/plugin/d/10080-rainbow-brackets.svg?style=flat-square"></a>
|
|
||||||
<a href="https://plugins.jetbrains.com/plugin/10080-rainbow-brackets"><img src="https://img.shields.io/jetbrains/plugin/v/10080-rainbow-brackets.svg?style=flat-square"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets#backer"><img src="https://img.shields.io/opencollective/backers/intellij-rainbow-brackets?style=flat-square"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets#sponsor"><img src="https://img.shields.io/opencollective/sponsors/intellij-rainbow-brackets?style=flat-square"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
- [Change log](https://github.com/izhangzhihao/intellij-rainbow-brackets/blob/2020.3/CHANGELOG.md)
|
|
||||||
- [Compatibility](#compatibility)
|
|
||||||
- [Supported languages](#supported-languages)
|
|
||||||
- [Author's choice](#authors-choice)
|
|
||||||
- [Sponsored By CodeStream](#sponsored-by-codestream)
|
|
||||||
- [Install](#install)
|
|
||||||
- [Screenshots](#screenshots)
|
|
||||||
- [Customize colors](#customize-colors)
|
|
||||||
- [Use color generator](#use-color-generator)
|
|
||||||
- [Config file path](#config-file-path)
|
|
||||||
- [HTML code in js](#html-code-in-js)
|
|
||||||
- [Kotlin function literal braces and arrow](#kotlin-function-literal-braces-and-arrow)
|
|
||||||
- [Disable rainbow brackets for specific languages](#disable-rainbow-brackets-for-specific-languages)
|
|
||||||
- [Contribute](#contribute)
|
|
||||||
- [Support Us](#support-us)
|
|
||||||
- [Backers](#backers)
|
|
||||||
- [Sponsors](#sponsors)
|
|
||||||
- [Acknowledgements](#acknowledgements)
|
|
||||||
|
|
||||||
## Compatibility
|
|
||||||
|
|
||||||
IntelliJ IDEA, PhpStorm, WebStorm, PyCharm, RubyMine, AppCode, CLion, Gogland, DataGrip, Rider, MPS, Android Studio, HUAWEI DevEco Studio, DataSpell, Code With Me
|
|
||||||
|
|
||||||
## Supported languages
|
|
||||||
|
|
||||||
Java, Scala, Clojure, Kotlin, Python, Haskell, Agda, Rust, JavaScript, TypeScript, Erlang, Go, Groovy, Ruby, Elixir, ObjectiveC, PHP, HTML, XML, SQL, Apex language, C#, Dart, Pug/Jade, Bash, Vue.js, C# Razor Pages, GLSL(the OpenGL Shading Language), Go Template, C++, C...
|
|
||||||
|
|
||||||
## Author's choice
|
|
||||||
|
|
||||||
Rainbow Brackets + One Dark Theme + Nyan Progress Bar + [Fira Code](https://github.com/tonsky/FiraCode) (Font)
|
|
||||||
|
|
||||||
## Sponsored By [CodeStream](https://sponsorlink.codestream.com/?utm_source=jbmarket&utm_campaign=jbrainbowbrackets&utm_medium=banner)
|
|
||||||
|
|
||||||
[![https://codestream.com](https://alt-images.codestream.com/codestream_logo_jbrainbowbrackets.png)](https://sponsorlink.codestream.com/?utm_source=jbmarket&utm_campaign=jbrainbowbrackets&utm_medium=banner)
|
|
||||||
|
|
||||||
Eliminate context switching and costly distractions. Create and merge PRs and perform code reviews from inside your IDE while using jump-to-definition, your keybindings, and other IDE favorites. [Learn more](https://sponsorlink.codestream.com/?utm_source=jbmarket&utm_campaign=jbrainbowbrackets&utm_medium=banner)!
|
|
||||||
|
|
||||||
Development powered by [JetBrains](https://www.jetbrains.com/?from=IntelliJRainbowBrackets).
|
|
||||||
|
|
||||||
[![https://www.jetbrains.com/?from=IntelliJRainbowBrackets](./screenshots/jetbrains.svg)](https://www.jetbrains.com/?from=IntelliJRainbowBrackets)
|
|
||||||
|
|
||||||
Whichever technologies you use, there's a JetBrains tool to match.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
<a href="https://plugins.jetbrains.com/embeddable/install/10080">
|
|
||||||
<img src="https://user-images.githubusercontent.com/12044174/123105697-94066100-d46a-11eb-9832-338cdf4e0612.png" width="300"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
Or you could install it inside your IDE:
|
|
||||||
|
|
||||||
For Windows & Linux - <kbd>File</kbd> > <kbd>Settings</kbd> > <kbd>Plugins</kbd> > <kbd>Marketplace</kbd> > <kbd>Search for "Rainbow Brackets"</kbd> > <kbd>Install Plugin</kbd> > <kbd>Restart IntelliJ IDEA</kbd>
|
|
||||||
|
|
||||||
For Mac - <kbd>IntelliJ IDEA</kbd> > <kbd>Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>Marketplace</kbd> > <kbd>Search for "Rainbow Brackets"</kbd> > <kbd>Install Plugin</kbd> > <kbd>Restart IntelliJ IDEA</kbd>
|
|
||||||
|
|
||||||
### Install snapshot build
|
|
||||||
|
|
||||||
You can download the latest snapshot build from [here](https://github.com/izhangzhihao/intellij-rainbow-brackets/actions/workflows/build.yml?query=workflow%3ABuild), just click the latest build and click the 'Artifacts' tab.(You need logged in via github) After the snapshot build downloaded, unzip it(via `unzip UnZipMe.zip`), and install the zip file(intellij-rainbow-brackets.zip[]()) by `Install Plugin from Disk...`.
|
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
|
|
||||||
* Java
|
|
||||||
|
|
||||||
![](./screenshots/with-java.png)
|
|
||||||
|
|
||||||
![](./screenshots/with-material-theme-ui.png)
|
|
||||||
|
|
||||||
* Scala
|
|
||||||
|
|
||||||
![](./screenshots/with-scala.png)
|
|
||||||
|
|
||||||
* Clojure
|
|
||||||
|
|
||||||
![](./screenshots/with-Clojure.png)
|
|
||||||
|
|
||||||
* Kotlin
|
|
||||||
|
|
||||||
![](./screenshots/with-kotlin.png)
|
|
||||||
|
|
||||||
* HTML/XML
|
|
||||||
|
|
||||||
![](./screenshots/with-HTML.png)
|
|
||||||
|
|
||||||
* Scope highlighting
|
|
||||||
|
|
||||||
**The highlight effects will not remove after release the shortcuts, but press `ESC` key can do this. You could also config `Press any key to remove the highlighting effect` in setting page.**
|
|
||||||
|
|
||||||
<kbd>Ctrl + Button3</kbd>(Windows & Linux) or <kbd>Meta+ Button3</kbd>(Mac):
|
|
||||||
|
|
||||||
NOTE: <kbd>Button3</kbd> means "Secondary Click (click or tap with two fingers)" on Mac os, "Right click" for Windows or Linux.
|
|
||||||
|
|
||||||
![](https://user-images.githubusercontent.com/10737066/40234968-46593fe2-5adb-11e8-8ea8-0026fad86ca9.gif)
|
|
||||||
|
|
||||||
<kbd>Alt + Button3</kbd>:
|
|
||||||
|
|
||||||
NOTE: <kbd>Button3</kbd> means "Secondary Click (click or tap with two fingers)" on Mac os, "Right click" for Windows or Linux.
|
|
||||||
|
|
||||||
![](https://user-images.githubusercontent.com/10737066/40235004-642dfe54-5adb-11e8-9fd7-648b92fab8f5.gif)
|
|
||||||
|
|
||||||
* Rainbow indent guide lines
|
|
||||||
|
|
||||||
![](https://user-images.githubusercontent.com/10737066/65765792-c41cb500-e15b-11e9-8877-2239c6afa7bf.gif)
|
|
||||||
|
|
||||||
* looking forward to your screenshots(PR welcome!)
|
|
||||||
|
|
||||||
## Customize colors
|
|
||||||
|
|
||||||
<kbd>Settings/Preferences</kbd> > <kbd>Editor</kbd> > <kbd>Color Scheme</kbd> > <kbd>Rainbow Brackets</kbd>:
|
|
||||||
|
|
||||||
![Customize colors](./screenshots/customize-colors.png)
|
|
||||||
|
|
||||||
## Use color generator
|
|
||||||
|
|
||||||
If you didn't like the build-in colors, or want some new color but don't want to try out and pick colors. Please use color generator.
|
|
||||||
|
|
||||||
<kbd>Settings/Preferences</kbd> > <kbd>Other Settings</kbd> > <kbd>Rainbow Brackets</kbd> > <kbd>Use color generator</kbd>
|
|
||||||
|
|
||||||
If you turn on this option, we will auto generate some colors for you.
|
|
||||||
|
|
||||||
### Advanced options of color generator
|
|
||||||
|
|
||||||
If you need more control, you can decide the options of color generator by edit [the config file](#config-file-path),
|
|
||||||
|
|
||||||
The value of the option `customColorGeneratorOption` is a json object, available options are:
|
|
||||||
|
|
||||||
```hue``` – Controls the hue of the generated color. You can pass a string representing a color name: ```red```, ```orange```, ```yellow```, ```green```, ```blue```, ```purple```, ```pink``` and ```monochrome``` are currently supported. If you pass a hexidecimal color string such as ```#00FFFF```, color generator will extract its hue value and use that to generate colors.
|
|
||||||
|
|
||||||
```luminosity``` – Controls the luminosity of the generated color. You can specify a string containing ```bright```, ```light``` or ```dark```.
|
|
||||||
|
|
||||||
Please make sure the value of the option `customColorGeneratorOption` is escaped in xml format,
|
|
||||||
you can use [this tool](https://www.freeformatter.com/xml-escape.html#ad-output) to do this. Please don't forget to restart your IDE after change the config file.
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<application>
|
|
||||||
<component name="RainbowSettings">
|
|
||||||
<option name="useColorGenerator" value="true" />
|
|
||||||
<option name="customColorGeneratorOption" value="{"luminosity": "light","hue": "blue"}"/>
|
|
||||||
</component>
|
|
||||||
</application>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Want to config the number of colors?
|
|
||||||
|
|
||||||
<kbd>Settings/Preferences</kbd> > <kbd>Other Settings</kbd> > <kbd>Rainbow Brackets</kbd> > `Number of colors`: 5 or more
|
|
||||||
|
|
||||||
And you can use the color generator and config you number of colors at the same time.
|
|
||||||
|
|
||||||
NOTE: For default and darcula color scheme(`Editor -> Color Scheme -> Rainbow Brackets -> Scheme`) the color number is 10, for the other scheme the number is 5, if your number is bigger than the number, you can config them in the config file.
|
|
||||||
If the color is not exist, we will use color generator to generator it for you.
|
|
||||||
|
|
||||||
Please follow [the official guide](https://www.jetbrains.com/help/idea/configuring-colors-and-fonts.html#share-color-scheme):
|
|
||||||
* `Export a color scheme as XML`
|
|
||||||
* Edit the xml file, put `ROUND_BRACKETS_RAINBOW_COLOR5` to `ROUND_BRACKETS_RAINBOW_COLOR100` to match your number just like [the default color scheme](./src/main/resources/colorSchemes/rainbow-color-default-darcula.xml).
|
|
||||||
* `Import a color scheme`
|
|
||||||
|
|
||||||
## Config file path
|
|
||||||
|
|
||||||
If you want to customize the advanced configuration, you could edit the config file then restart your IDE.
|
|
||||||
Config file path in `APP_CONFIG/rainbow_brackets.xml`.
|
|
||||||
|
|
||||||
In MAC OS env maybe like `~/Library/Preferences/IntelliJIdea2020.2/options/rainbow_brackets.xml`.
|
|
||||||
|
|
||||||
If you are using the ToolBox, then it will be like `~/Library/ApplicationSupport/JetBrains/IntelliJIdea2020.2/options/rainbow_brackets.xml`
|
|
||||||
|
|
||||||
In Linux env maybe like `~/.IntelliJIdea/config/options/rainbow_brackets.xml`.
|
|
||||||
|
|
||||||
In Windows env maybe like `C:\Users\izhangzhihao\.IntelliJIdea2020.2\config\options\rainbow_brackets.xml`.
|
|
||||||
|
|
||||||
## HTML code in js
|
|
||||||
|
|
||||||
To enable rainbow brackets for HTML inside js code like this:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var html = '<div><div><div>Hello</div></div></div>';
|
|
||||||
```
|
|
||||||
|
|
||||||
This plugin will automatically override color scheme property "HTML_CODE" [cause our rainbow color been covered by intellij built-in functionality](https://intellij-support.jetbrains.com/hc/en-us/community/posts/360000117450-My-HighlightVisitor-been-covered-by-intellij-built-in-functionality).
|
|
||||||
You still could set `<option name="rainbowifyHTMLInsideJS" value="false" />` in config file to disable.
|
|
||||||
|
|
||||||
## Kotlin function literal braces and arrow
|
|
||||||
|
|
||||||
To enable rainbow brackets for multiple level lambda Kotlin code like this:
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
event.throwable?.let { throwable ->
|
|
||||||
IdeErrorsDialog.findPluginId(throwable)?.let { pluginId ->
|
|
||||||
PluginManager.getPlugin(pluginId)?.let { ideaPluginDescriptor ->
|
|
||||||
if (!ideaPluginDescriptor.isBundled) {
|
|
||||||
bean.pluginName = ideaPluginDescriptor.name
|
|
||||||
bean.pluginVersion = ideaPluginDescriptor.version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This plugin will automatically override color scheme property "KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW" cause our rainbow color is being covered by kotlin plugin built-in functionality.
|
|
||||||
You still could set `<option name="rainbowifyKotlinFunctionLiteralBracesAndArrow" value="false" />` in config file to disable.
|
|
||||||
|
|
||||||
## Disable rainbow brackets for specific languages
|
|
||||||
|
|
||||||
<kbd>Settings/Preferences</kbd> > <kbd>Other Settings</kbd> > <kbd>Rainbow Brackets</kbd> > `Do NOT rainbowify these languages (name or extension, comma separated)`:
|
|
||||||
|
|
||||||
NOTE: You can use **name** of language or **extension** of file name(The names should be **lowercase**).
|
|
||||||
|
|
||||||
## Contribute
|
|
||||||
|
|
||||||
NOTE: To view the PSI tree and explore the internal PSI structure of source code, you need to set up your IDE by following [this](https://www.jetbrains.com/help/idea/psi-viewer.html).
|
|
||||||
For the Rider IDE, please follow: [this](https://rider-support.jetbrains.com/hc/en-us/articles/207327910-How-to-run-JetBrains-Rider-in-Internal-Mode)
|
|
||||||
|
|
||||||
* `gradle test`
|
|
||||||
* `gradle runIde`
|
|
||||||
* `gradle buildPlugin`
|
|
||||||
|
|
||||||
## Support Us
|
|
||||||
|
|
||||||
You can support us by the following actions:
|
|
||||||
|
|
||||||
* Star this project
|
|
||||||
* Share this plugin with your friends
|
|
||||||
* Rate this plugin on [JetBrains plugin repository](https://plugins.jetbrains.com/plugin/10080-rainbow-brackets)
|
|
||||||
* Make pull requests
|
|
||||||
* Report bugs
|
|
||||||
* Tell us your ideas
|
|
||||||
* Become a sponsor by donating on [Open Collective](https://opencollective.com/intellij-rainbow-brackets)
|
|
||||||
* Become a sponsor by donating with AliPay or WeChatPay
|
|
||||||
* Don't want to use AliPay's mobile App? If you could read Chinese, please use [the official website](https://shenghuo.alipay.com/send/payment/fill.htm) to transfer your donation to my Alipay account(izhangzhihao@hotmail.com). Otherwise, you can try [the English version of Alipay](https://global.alipay.com/) to transfer your donation.
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th width="33%">Open Collective</th>
|
|
||||||
<th width="33%">AliPay</th>
|
|
||||||
<th width="33%">WeChatPay</th>
|
|
||||||
</tr>
|
|
||||||
<tr></tr>
|
|
||||||
<tr align="center">
|
|
||||||
<td>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets" target="_blank">
|
|
||||||
<img src="https://opencollective.com/static/images/opencollectivelogo-footer-n.svg" width="171px" alt="OpenCollective">
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td><img src="https://user-images.githubusercontent.com/12044174/85197261-77dd5a80-b312-11ea-9630-51caf7d634f2.jpg"></td>
|
|
||||||
<td><img src="https://user-images.githubusercontent.com/12044174/85197263-7b70e180-b312-11ea-917a-35eab2ea08ae.jpg"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## Backers
|
|
||||||
|
|
||||||
Thank you to all our backers! ❤️ [[Become a backer](https://opencollective.com/intellij-rainbow-brackets#backer)]
|
|
||||||
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets#backers" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/backers.svg?width=890"></a>
|
|
||||||
|
|
||||||
## Sponsors
|
|
||||||
|
|
||||||
Support this project by becoming a sponsor! 🌈 Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/intellij-rainbow-brackets#sponsor)]
|
|
||||||
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/0/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/0/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/1/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/1/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/2/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/2/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/3/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/3/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/4/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/4/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/5/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/5/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/6/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/6/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/7/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/7/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/8/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/8/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/9/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/9/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/10/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/10/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/11/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/11/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/12/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/12/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/13/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/13/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/14/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/14/avatar.svg"></a>
|
|
||||||
<a href="https://opencollective.com/intellij-rainbow-brackets/sponsor/15/website" target="_blank"><img src="https://opencollective.com/intellij-rainbow-brackets/sponsor/15/avatar.svg"></a>
|
|
||||||
|
|
||||||
## Acknowledgements
|
|
||||||
|
|
||||||
Intellij-rainbow-brackets is heavily inspired by [Rainbow Brackets for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=2gua.rainbow-brackets)
|
|
||||||
|
131
build.gradle.kts
@ -1,103 +1,70 @@
|
|||||||
import org.jetbrains.intellij.tasks.RunPluginVerifierTask.FailureLevel.*
|
@file:Suppress("ConvertLambdaToReference")
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
val name: String by project
|
|
||||||
val ideaVersion: String by project
|
|
||||||
val kotlinVersion: String by project
|
|
||||||
val javaVersion: String by project
|
|
||||||
val kotlinLanguageVersion: String by project
|
|
||||||
val kotlinTargetVersion: String by project
|
|
||||||
val pluginVerifierIdeVersions: String by project
|
|
||||||
val publishChannels: String by project
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("org.jetbrains.intellij") version "1.9.0"
|
kotlin("jvm") version "1.9.21"
|
||||||
id("com.adarshr.test-logger") version "3.2.0"
|
id("org.jetbrains.intellij") version "1.17.4"
|
||||||
id("org.jetbrains.kotlin.jvm") version "1.7.20"
|
|
||||||
id("idea")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group = "com.chylex.intellij.coloredbrackets"
|
||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenCentral()
|
||||||
mavenCentral()
|
|
||||||
maven(url = "https://maven-central.storage-download.googleapis.com/repos/central/data/")
|
|
||||||
maven(url = "https://maven.aliyun.com/nexus/content/groups/public/")
|
|
||||||
maven(url = "https://www.jetbrains.com/intellij-repository/releases")
|
|
||||||
maven(url = "https://www.jetbrains.com/intellij-repository/snapshots")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intellij {
|
intellij {
|
||||||
pluginName.set(name)
|
type.set("IU")
|
||||||
|
version.set("2023.3")
|
||||||
|
updateSinceUntilBuild.set(false)
|
||||||
|
|
||||||
version.set(ideaVersion)
|
plugins.set(
|
||||||
//localPath = '/Users/izhangzhihao/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/201.6668.121/IntelliJ IDEA 2020.1 EAP.app/Contents'
|
listOf(
|
||||||
//localPath = '/Users/izhangzhihao/Library/Application Support/JetBrains/Toolbox/apps/CLion/ch-0/201.6668.126/CLion.app/Contents'
|
// Built-in
|
||||||
updateSinceUntilBuild.set(false)
|
"Groovy",
|
||||||
|
"JavaScript",
|
||||||
plugins.set(
|
"com.intellij.css",
|
||||||
listOf(
|
"com.intellij.database",
|
||||||
"java",
|
"com.intellij.java",
|
||||||
"java-i18n",
|
"org.intellij.plugins.markdown",
|
||||||
"JavaScriptLanguage",
|
"org.jetbrains.kotlin",
|
||||||
"DatabaseTools",
|
"org.jetbrains.plugins.yaml",
|
||||||
"CSS",
|
// Downloaded
|
||||||
"platform-images",
|
"Dart:233.11799.172", // https://plugins.jetbrains.com/plugin/6351-dart/versions/stable
|
||||||
"Groovy",
|
"Pythonid:233.11799.300", // https://plugins.jetbrains.com/plugin/631-python/versions
|
||||||
"properties",
|
"com.jetbrains.php:233.11799.300", // https://plugins.jetbrains.com/plugin/6610-php/versions
|
||||||
"yaml",
|
"com.jetbrains.sh:233.11799.165", // https://plugins.jetbrains.com/plugin/13122-shell-script/versions
|
||||||
"org.jetbrains.kotlin:203-$kotlinVersion-release-IJ5981.133-1",
|
"org.intellij.scala:2023.3.19", // https://plugins.jetbrains.com/plugin/1347-scala/versions
|
||||||
"org.intellij.scala:2020.3.21",
|
"org.jetbrains.plugins.go-template:233.11799.172", // https://plugins.jetbrains.com/plugin/10581-go-template/versions
|
||||||
"Dart:203.5981.155",
|
"org.jetbrains.plugins.ruby:233.11799.300", // https://plugins.jetbrains.com/plugin/1293-ruby/versions
|
||||||
"org.jetbrains.plugins.ruby:203.5981.155",
|
)
|
||||||
"com.jetbrains.php:203.5981.155",
|
)
|
||||||
"com.jetbrains.sh:203.5981.37",
|
|
||||||
"com.jetbrains.plugins.jade:203.5981.155",
|
|
||||||
"org.jetbrains.plugins.go-template:203.5981.155",
|
|
||||||
"Pythonid:203.5981.155",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
kotlin {
|
||||||
runIde {
|
jvmToolchain(17)
|
||||||
systemProperties["idea.auto.reload.plugins"] = false
|
|
||||||
jvmArgs = listOf(
|
|
||||||
"-Xms512m",
|
|
||||||
"-Xmx2048m",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
publishPlugin {
|
|
||||||
token.set(System.getenv("token"))
|
|
||||||
channels.set(publishChannels.split(",").map { it.trim() }.toList())
|
|
||||||
}
|
|
||||||
|
|
||||||
runPluginVerifier {
|
|
||||||
ideVersions.set(pluginVerifierIdeVersions.split(",").map { it.trim() }.toList())
|
|
||||||
failureLevel.set(listOf(COMPATIBILITY_PROBLEMS))
|
|
||||||
}
|
|
||||||
|
|
||||||
testlogger {
|
|
||||||
theme = com.adarshr.gradle.testlogger.theme.ThemeType.MOCHA
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
//implementation("org.eclipse.mylyn.github:org.eclipse.egit.github.core:5.11.0.202103091610-r") {
|
compileOnly(fileTree("libs"))
|
||||||
// exclude("gson")
|
|
||||||
//}
|
testImplementation("junit:junit:4.13.2")
|
||||||
compileOnly(fileTree("libs"))
|
testImplementation("io.kotest:kotest-assertions-core:5.8.0") {
|
||||||
testImplementation("io.kotest:kotest-assertions-core:5.5.0")
|
exclude(group = "org.jetbrains.kotlin")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
tasks.patchPluginXml {
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sinceBuild.set("233")
|
||||||
targetCompatibility = JavaVersion.VERSION_11
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnit()
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
tasks.withType<KotlinCompile> {
|
||||||
kotlinOptions.languageVersion = kotlinLanguageVersion
|
kotlinOptions.freeCompilerArgs = listOf(
|
||||||
kotlinOptions.apiVersion = kotlinTargetVersion
|
"-Xjvm-default=all"
|
||||||
kotlinOptions.jvmTarget = javaVersion
|
)
|
||||||
kotlinOptions.freeCompilerArgs = listOf("-Xskip-runtime-version-check", "-Xjsr305=strict")
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1 @@
|
|||||||
group="com.github.izhangzhihao"
|
|
||||||
name="Rainbow Brackets"
|
|
||||||
org.gradle.parallel=true
|
|
||||||
ideaVersion=IU-203.5981.155
|
|
||||||
javaVersion=11
|
|
||||||
kotlinVersion=1.4.21
|
|
||||||
kotlinLanguageVersion=1.4
|
|
||||||
kotlinTargetVersion=1.4
|
|
||||||
version=6.26
|
|
||||||
publishChannels=Stable
|
|
||||||
kotlin.stdlib.default.dependency=false
|
kotlin.stdlib.default.dependency=false
|
||||||
pluginVerifierIdeVersions=WS-2020.3, IIC-2021.1, IIU-2021.2
|
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
294
gradlew
vendored
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -17,67 +17,99 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
# This is normally unused
|
||||||
APP_BASE_NAME=`basename "$0"`
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MSYS* | MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
@ -87,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@ -98,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
# shellcheck disable=SC2039,SC3045
|
||||||
fi
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
ulimit -n $MAX_FD
|
warn "Could not query maximum file descriptor limit"
|
||||||
if [ $? -ne 0 ] ; then
|
esac
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
case $MAX_FD in #(
|
||||||
fi
|
'' | soft) :;; #(
|
||||||
else
|
*)
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
fi
|
# shellcheck disable=SC2039,SC3045
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=`save "$@"`
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
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, 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" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
15
gradlew.bat
vendored
@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@ -25,7 +25,8 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
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 |
Before Width: | Height: | Size: 102 KiB |
@ -1,6 +1 @@
|
|||||||
pluginManagement {
|
rootProject.name = "ColoredBrackets"
|
||||||
repositories {
|
|
||||||
maven(url = "https://oss.sonatype.org/content/repositories/snapshots/")
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,75 +3,84 @@ package com.github.izhangzhihao.rainbow.brackets
|
|||||||
import com.github.izhangzhihao.rainbow.brackets.provider.BracePairProvider
|
import com.github.izhangzhihao.rainbow.brackets.provider.BracePairProvider
|
||||||
import com.github.izhangzhihao.rainbow.brackets.util.memoize
|
import com.github.izhangzhihao.rainbow.brackets.util.memoize
|
||||||
import com.intellij.codeInsight.highlighting.BraceMatchingUtil
|
import com.intellij.codeInsight.highlighting.BraceMatchingUtil
|
||||||
import com.intellij.lang.*
|
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
|
import com.intellij.psi.tree.IElementType
|
||||||
|
|
||||||
object BracePairs {
|
object BracePairs {
|
||||||
|
|
||||||
private val providers = LanguageExtension<BracePairProvider>("izhangzhihao.rainbow.brackets.bracePairProvider")
|
private val providers = LanguageExtension<BracePairProvider>("com.chylex.coloredbrackets.bracePairProvider")
|
||||||
|
|
||||||
private val bracePairs =
|
private val bracePairs =
|
||||||
Language.getRegisteredLanguages()
|
Language.getRegisteredLanguages()
|
||||||
.map { language ->
|
.map { language ->
|
||||||
if (language is CompositeLanguage) {
|
if (language is CompositeLanguage) {
|
||||||
return@map language.displayName to null
|
return@map language.displayName to null
|
||||||
}
|
}
|
||||||
|
|
||||||
val pairs =
|
val pairs =
|
||||||
LanguageBraceMatching.INSTANCE.forLanguage(language)?.pairs.let {
|
LanguageBraceMatching.INSTANCE.forLanguage(language)?.pairs.let {
|
||||||
if (it == null || it.isEmpty()) {
|
if (it.isNullOrEmpty()) {
|
||||||
language.associatedFileType
|
language.associatedFileType
|
||||||
?.let { fileType -> BraceMatchingUtil.getBraceMatcher(fileType, language) as? PairedBraceMatcher }
|
?.let { fileType -> BraceMatchingUtil.getBraceMatcher(fileType, language) as? PairedBraceMatcher }
|
||||||
?.pairs
|
?.pairs
|
||||||
} else {
|
}
|
||||||
it
|
else {
|
||||||
}
|
it
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val pairsList = providers.forLanguage(language)?.pairs()?.let {
|
val pairsList = providers.forLanguage(language)?.pairs()?.let {
|
||||||
if (pairs != null && pairs.isNotEmpty()) {
|
if (!pairs.isNullOrEmpty()) {
|
||||||
it.toMutableSet().apply { addAll(pairs) }
|
it.toMutableSet().apply { addAll(pairs) }
|
||||||
} else {
|
}
|
||||||
it
|
else {
|
||||||
}
|
it
|
||||||
} ?: pairs?.toList()
|
}
|
||||||
|
} ?: pairs?.toList()
|
||||||
|
|
||||||
val braceMap: MutableMap<String, MutableList<BracePair>> = mutableMapOf()
|
val braceMap: MutableMap<String, MutableList<BracePair>> = mutableMapOf()
|
||||||
|
|
||||||
val blackSet = providers.forLanguage(language)?.blackList()?.map { it.toString() }?.toSet()
|
val blackSet = providers.forLanguage(language)?.blackList()?.map { it.toString() }?.toSet()
|
||||||
|
|
||||||
pairsList
|
pairsList
|
||||||
?.filter {
|
?.filter {
|
||||||
if (blackSet != null) {
|
if (blackSet != null) {
|
||||||
!blackSet.contains(it.toString())
|
!blackSet.contains(it.toString())
|
||||||
} else {
|
}
|
||||||
true
|
else {
|
||||||
}
|
true
|
||||||
}
|
}
|
||||||
?.map { listOf(Pair(it.leftBraceType.toString(), it), Pair(it.rightBraceType.toString(), it)) }
|
}
|
||||||
?.flatten()
|
?.map { listOf(Pair(it.leftBraceType.toString(), it), Pair(it.rightBraceType.toString(), it)) }
|
||||||
?.forEach { it ->
|
?.flatten()
|
||||||
val bracePairs = braceMap[it.first]
|
?.forEach {
|
||||||
if (bracePairs == null) {
|
val bracePairs = braceMap[it.first]
|
||||||
braceMap[it.first] = mutableListOf(it.second)
|
if (bracePairs == null) {
|
||||||
} else {
|
braceMap[it.first] = mutableListOf(it.second)
|
||||||
bracePairs.add(it.second)
|
}
|
||||||
}
|
else {
|
||||||
}
|
bracePairs.add(it.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
language.displayName to braceMap
|
language.displayName to braceMap
|
||||||
}
|
}
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
fun getBracePairs(language: Language): MutableMap<String, MutableList<BracePair>>? = bracePairs[language.displayName]
|
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()
|
private fun getBraceTypeSetOf(language: Language): Set<IElementType> = getBracePairs(language)?.values?.flatten()?.map { listOf(it.leftBraceType, it.rightBraceType) }?.flatten()?.toSet() ?: emptySet()
|
||||||
|
|
||||||
val braceTypeSet: (Language) -> Set<IElementType> = { language: Language -> getBraceTypeSetOf(language) }.memoize()
|
val braceTypeSet: (Language) -> Set<IElementType> = { language: Language -> getBraceTypeSetOf(language) }.memoize()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline val Language.bracePairs: MutableMap<String, MutableList<BracePair>>?
|
inline val Language.bracePairs: MutableMap<String, MutableList<BracePair>>?
|
||||||
get() = BracePairs.getBracePairs(this)
|
get() = BracePairs.getBracePairs(this)
|
||||||
|
|
||||||
inline val Language.braceTypeSet: Set<IElementType>
|
inline val Language.braceTypeSet: Set<IElementType>
|
||||||
get() = BracePairs.braceTypeSet(this)
|
get() = BracePairs.braceTypeSet(this)
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets
|
|
||||||
|
|
||||||
import com.intellij.notification.*
|
|
||||||
import com.intellij.notification.impl.NotificationsManagerImpl
|
|
||||||
import com.intellij.openapi.Disposable
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.ui.popup.Balloon
|
|
||||||
import com.intellij.openapi.wm.WindowManager
|
|
||||||
import com.intellij.ui.BalloonLayoutData
|
|
||||||
import com.intellij.ui.awt.RelativePoint
|
|
||||||
import java.awt.Point
|
|
||||||
|
|
||||||
class ApplicationServicePlaceholder : Disposable {
|
|
||||||
override fun dispose() = Unit
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val INSTANCE: ApplicationServicePlaceholder = ApplicationManager.getApplication().getService(ApplicationServicePlaceholder::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createNotification(title: String, content: String, type: NotificationType,
|
|
||||||
listener: NotificationListener): Notification {
|
|
||||||
return NotificationGroupManager.getInstance().getNotificationGroup("Rainbow Brackets Notification Group")
|
|
||||||
.createNotification(title, content, type).setListener(listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun showFullNotification(project: Project, notification: Notification) {
|
|
||||||
val frame = WindowManager.getInstance().getIdeFrame(project)
|
|
||||||
if (frame == null) {
|
|
||||||
notification.notify(project)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val bounds = frame.component.bounds
|
|
||||||
val target = RelativePoint(frame.component, Point(bounds.x + bounds.width, 20))
|
|
||||||
|
|
||||||
try {
|
|
||||||
val balloon = NotificationsManagerImpl.createBalloon(frame,
|
|
||||||
notification,
|
|
||||||
true, // showCallout
|
|
||||||
true, // hideOnClickOutside
|
|
||||||
BalloonLayoutData.fullContent(),
|
|
||||||
ApplicationServicePlaceholder.INSTANCE)
|
|
||||||
balloon.show(target, Balloon.Position.atLeft)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
notification.notify(project)
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,199 +19,207 @@ import org.intellij.lang.annotations.Language
|
|||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.awt.Font
|
import java.awt.Font
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
object RainbowHighlighter {
|
object RainbowHighlighter {
|
||||||
|
|
||||||
val DEFAULT_KOTLIN_LABEL_COLOR = JBColor(0x4a86e8, 0x467cda)
|
val DEFAULT_KOTLIN_LABEL_COLOR = JBColor(0x4a86e8, 0x467cda)
|
||||||
|
|
||||||
const val NAME_ROUND_BRACKETS = "Round Brackets"
|
const val NAME_ROUND_BRACKETS = "Round Brackets"
|
||||||
const val NAME_SQUARE_BRACKETS = "Square Brackets"
|
const val NAME_SQUARE_BRACKETS = "Square Brackets"
|
||||||
const val NAME_SQUIGGLY_BRACKETS = "Squiggly Brackets"
|
const val NAME_SQUIGGLY_BRACKETS = "Squiggly Brackets"
|
||||||
const val NAME_ANGLE_BRACKETS = "Angle Brackets"
|
const val NAME_ANGLE_BRACKETS = "Angle Brackets"
|
||||||
|
|
||||||
private const val KEY_ROUND_BRACKETS = "ROUND_BRACKETS_RAINBOW_COLOR"
|
private const val KEY_ROUND_BRACKETS = "ROUND_BRACKETS_RAINBOW_COLOR"
|
||||||
private const val KEY_SQUARE_BRACKETS = "SQUARE_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_SQUIGGLY_BRACKETS = "SQUIGGLY_BRACKETS_RAINBOW_COLOR"
|
||||||
private const val KEY_ANGLE_BRACKETS = "ANGLE_BRACKETS_RAINBOW_COLOR"
|
private const val KEY_ANGLE_BRACKETS = "ANGLE_BRACKETS_RAINBOW_COLOR"
|
||||||
|
|
||||||
private val roundBrackets: CharArray = charArrayOf('(', ')')
|
private val roundBrackets: CharArray = charArrayOf('(', ')')
|
||||||
private val squareBrackets: CharArray = charArrayOf('[', ']')
|
private val squareBrackets: CharArray = charArrayOf('[', ']')
|
||||||
private val squigglyBrackets: CharArray = charArrayOf('{', '}')
|
private val squigglyBrackets: CharArray = charArrayOf('{', '}')
|
||||||
private val angleBrackets: CharArray = charArrayOf('<', '>')
|
private val angleBrackets: CharArray = charArrayOf('<', '>')
|
||||||
|
|
||||||
private val settings = RainbowSettings.instance
|
private val settings = RainbowSettings.instance
|
||||||
|
|
||||||
private val roundBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
private val roundBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||||
createRainbowAttributesKeys(KEY_ROUND_BRACKETS, settings.numberOfColors)
|
createRainbowAttributesKeys(KEY_ROUND_BRACKETS, settings.numberOfColors)
|
||||||
private val squareBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
private val squareBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||||
createRainbowAttributesKeys(KEY_SQUARE_BRACKETS, settings.numberOfColors)
|
createRainbowAttributesKeys(KEY_SQUARE_BRACKETS, settings.numberOfColors)
|
||||||
private val squigglyBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
private val squigglyBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||||
createRainbowAttributesKeys(KEY_SQUIGGLY_BRACKETS, settings.numberOfColors)
|
createRainbowAttributesKeys(KEY_SQUIGGLY_BRACKETS, settings.numberOfColors)
|
||||||
private val angleBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
private val angleBracketsRainbowColorKeys: Array<TextAttributesKey> =
|
||||||
createRainbowAttributesKeys(KEY_ANGLE_BRACKETS, settings.numberOfColors)
|
createRainbowAttributesKeys(KEY_ANGLE_BRACKETS, settings.numberOfColors)
|
||||||
|
|
||||||
private val rainbowElement: HighlightInfoType = HighlightInfoType
|
private val rainbowElement: HighlightInfoType = HighlightInfoType
|
||||||
.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, DefaultLanguageHighlighterColors.CONSTANT)
|
.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, DefaultLanguageHighlighterColors.CONSTANT)
|
||||||
|
|
||||||
private val PsiElement.isRoundBracket get() = roundBrackets.any { textContains(it) }
|
private val PsiElement.isRoundBracket get() = roundBrackets.any { textContains(it) }
|
||||||
private val PsiElement.isSquareBracket get() = squareBrackets.any { textContains(it) }
|
private val PsiElement.isSquareBracket get() = squareBrackets.any { textContains(it) }
|
||||||
private val PsiElement.isSquigglyBracket get() = squigglyBrackets.any { textContains(it) }
|
private val PsiElement.isSquigglyBracket get() = squigglyBrackets.any { textContains(it) }
|
||||||
private val PsiElement.isAngleBracket get() = angleBrackets.any { textContains(it) }
|
private val PsiElement.isAngleBracket get() = angleBrackets.any { textContains(it) }
|
||||||
|
|
||||||
private fun createRainbowAttributesKeys(keyName: String, size: Int): Array<TextAttributesKey> {
|
private fun createRainbowAttributesKeys(keyName: String, size: Int): Array<TextAttributesKey> {
|
||||||
return generateSequence(0) { it + 1 }
|
return generateSequence(0) { it + 1 }
|
||||||
.map { TextAttributesKey.createTextAttributesKey("$keyName$it") }
|
.map { TextAttributesKey.createTextAttributesKey("$keyName$it") }
|
||||||
.take(size)
|
.take(size)
|
||||||
.toList()
|
.toList()
|
||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRainbowAttributesKeys(rainbowName: String): Array<TextAttributesKey> {
|
fun getRainbowAttributesKeys(rainbowName: String): Array<TextAttributesKey> {
|
||||||
return when (rainbowName) {
|
return when (rainbowName) {
|
||||||
NAME_ROUND_BRACKETS -> roundBracketsRainbowColorKeys
|
NAME_ROUND_BRACKETS -> roundBracketsRainbowColorKeys
|
||||||
NAME_SQUARE_BRACKETS -> squareBracketsRainbowColorKeys
|
NAME_SQUARE_BRACKETS -> squareBracketsRainbowColorKeys
|
||||||
NAME_SQUIGGLY_BRACKETS -> squigglyBracketsRainbowColorKeys
|
NAME_SQUIGGLY_BRACKETS -> squigglyBracketsRainbowColorKeys
|
||||||
NAME_ANGLE_BRACKETS -> angleBracketsRainbowColorKeys
|
NAME_ANGLE_BRACKETS -> angleBracketsRainbowColorKeys
|
||||||
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Meta properties(SchemeMetaInfo) should be used.
|
// FIXME: Meta properties(SchemeMetaInfo) should be used.
|
||||||
fun isRainbowEnabled(rainbowName: String): Boolean {
|
fun isRainbowEnabled(rainbowName: String): Boolean {
|
||||||
return when (rainbowName) {
|
return when (rainbowName) {
|
||||||
NAME_ROUND_BRACKETS -> settings.isEnableRainbowRoundBrackets
|
NAME_ROUND_BRACKETS -> settings.isEnableRainbowRoundBrackets
|
||||||
NAME_SQUARE_BRACKETS -> settings.isEnableRainbowSquareBrackets
|
NAME_SQUARE_BRACKETS -> settings.isEnableRainbowSquareBrackets
|
||||||
NAME_SQUIGGLY_BRACKETS -> settings.isEnableRainbowSquigglyBrackets
|
NAME_SQUIGGLY_BRACKETS -> settings.isEnableRainbowSquigglyBrackets
|
||||||
NAME_ANGLE_BRACKETS -> settings.isEnableRainbowAngleBrackets
|
NAME_ANGLE_BRACKETS -> settings.isEnableRainbowAngleBrackets
|
||||||
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Meta properties(SchemeMetaInfo) should be used.
|
// FIXME: Meta properties(SchemeMetaInfo) should be used.
|
||||||
fun setRainbowEnabled(rainbowName: String, enabled: Boolean) {
|
fun setRainbowEnabled(rainbowName: String, enabled: Boolean) {
|
||||||
when (rainbowName) {
|
when (rainbowName) {
|
||||||
NAME_ROUND_BRACKETS -> settings.isEnableRainbowRoundBrackets = enabled
|
NAME_ROUND_BRACKETS -> settings.isEnableRainbowRoundBrackets = enabled
|
||||||
NAME_SQUARE_BRACKETS -> settings.isEnableRainbowSquareBrackets = enabled
|
NAME_SQUARE_BRACKETS -> settings.isEnableRainbowSquareBrackets = enabled
|
||||||
NAME_SQUIGGLY_BRACKETS -> settings.isEnableRainbowSquigglyBrackets = enabled
|
NAME_SQUIGGLY_BRACKETS -> settings.isEnableRainbowSquigglyBrackets = enabled
|
||||||
NAME_ANGLE_BRACKETS -> settings.isEnableRainbowAngleBrackets = enabled
|
NAME_ANGLE_BRACKETS -> settings.isEnableRainbowAngleBrackets = enabled
|
||||||
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
else -> throw IllegalArgumentException("Unknown rainbow name: $rainbowName")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isDarkEditor() = EditorColorsManager.getInstance().isDarkEditor
|
private fun isDarkEditor() = EditorColorsManager.getInstance().isDarkEditor
|
||||||
|
|
||||||
fun getRainbowColorByLevel(colorsScheme: TextAttributesScheme, rainbowName: String, level: Int): TextAttributesKey {
|
fun getRainbowColorByLevel(colorsScheme: TextAttributesScheme, rainbowName: String, level: Int): TextAttributesKey {
|
||||||
val ind = level % settings.numberOfColors
|
val ind = level % settings.numberOfColors
|
||||||
if (settings.useColorGenerator) {
|
if (settings.useColorGenerator) {
|
||||||
return memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
return memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
||||||
}
|
}
|
||||||
val key = getRainbowAttributesKeys(rainbowName).getOrNull(ind)
|
val key = getRainbowAttributesKeys(rainbowName).getOrNull(ind)
|
||||||
return try {
|
return try {
|
||||||
val result = colorsScheme.getAttributes(key)
|
val result = colorsScheme.getAttributes(key)
|
||||||
if (key == null || result == null || result.foregroundColor == null) {
|
if (key == null || result == null || result.foregroundColor == null) {
|
||||||
memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
||||||
} else {
|
}
|
||||||
key
|
else {
|
||||||
}
|
key
|
||||||
} catch (e: Exception) {
|
}
|
||||||
memGetRainbowColorByLevel(isDarkEditor(), rainbowName, ind)
|
} 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 {
|
||||||
private fun generateColor(isDark: Boolean, rainbowName: String, level: Int): TextAttributesKey {
|
if (!settings.customColorGeneratorOption.isNullOrBlank()) {
|
||||||
if (!settings.customColorGeneratorOption.isNullOrBlank()) {
|
return genByOption(settings.customColorGeneratorOption!!, rainbowName, level)
|
||||||
return genByOption(settings.customColorGeneratorOption!!, rainbowName, level)
|
}
|
||||||
}
|
if (isDark) {
|
||||||
if (isDark) {
|
@Language("JSON") val darkOption = """{"luminosity": "light"}"""
|
||||||
@Language("JSON") val darkOption = """{"luminosity": "light"}"""
|
return genByOption(darkOption, rainbowName, level)
|
||||||
return genByOption(darkOption, rainbowName, level)
|
}
|
||||||
}
|
@Language("JSON") val lightOption = """{"luminosity": "dark"}"""
|
||||||
@Language("JSON") val lightOption = """{"luminosity": "dark"}"""
|
return genByOption(lightOption, rainbowName, level)
|
||||||
return genByOption(lightOption, rainbowName, level)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun genByOption(option: String, rainbowName: String, level: Int) =
|
private fun genByOption(option: String, rainbowName: String, level: Int) =
|
||||||
com.github.izhangzhihao.rainbow.brackets.util.create("$rainbowName-$level",
|
com.github.izhangzhihao.rainbow.brackets.util.create(
|
||||||
TextAttributes(randomColor(option), null, null, null, 0))
|
"$rainbowName-$level",
|
||||||
|
TextAttributes(randomColor(option), null, null, null, 0)
|
||||||
|
)
|
||||||
|
|
||||||
val memGetRainbowColorByLevel = { isDark: Boolean, rainbowName: String, level: Int -> generateColor(isDark, rainbowName, level) }.memoize()
|
val memGetRainbowColorByLevel = { isDark: Boolean, rainbowName: String, level: Int -> generateColor(isDark, rainbowName, level) }.memoize()
|
||||||
|
|
||||||
@TestOnly
|
@TestOnly
|
||||||
fun getBrackets(): CharArray = roundBrackets + squareBrackets + squigglyBrackets + angleBrackets
|
fun getBrackets(): CharArray = roundBrackets + squareBrackets + squigglyBrackets + angleBrackets
|
||||||
|
|
||||||
@TestOnly
|
@TestOnly
|
||||||
fun getRainbowColor(rainbowName: String, level: Int): Color? {
|
fun getRainbowColor(rainbowName: String, level: Int): Color? {
|
||||||
return getRainbowColorByLevel(EditorColorsManager.getInstance().globalScheme, rainbowName, level).defaultAttributes.foregroundColor
|
return getRainbowColorByLevel(EditorColorsManager.getInstance().globalScheme, rainbowName, level).defaultAttributes.foregroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTextAttributes(colorsScheme: TextAttributesScheme,
|
private fun getTextAttributes(
|
||||||
element: PsiElement,
|
colorsScheme: TextAttributesScheme,
|
||||||
level: Int): TextAttributesKey? {
|
element: PsiElement,
|
||||||
if (!settings.isRainbowEnabled) {
|
level: Int,
|
||||||
return null
|
): TextAttributesKey? {
|
||||||
}
|
if (!settings.isRainbowEnabled) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
val rainbowName = when {
|
val rainbowName = when {
|
||||||
settings.applyColorsOfRoundForAllBrackets -> NAME_ROUND_BRACKETS
|
settings.applyColorsOfRoundForAllBrackets -> NAME_ROUND_BRACKETS
|
||||||
element.isRoundBracket -> if (settings.isEnableRainbowRoundBrackets) NAME_ROUND_BRACKETS else null
|
element.isRoundBracket -> if (settings.isEnableRainbowRoundBrackets) NAME_ROUND_BRACKETS else null
|
||||||
element.isSquareBracket -> if (settings.isEnableRainbowSquareBrackets) NAME_SQUARE_BRACKETS else null
|
element.isSquareBracket -> if (settings.isEnableRainbowSquareBrackets) NAME_SQUARE_BRACKETS else null
|
||||||
element.isSquigglyBracket -> if (settings.isEnableRainbowSquigglyBrackets) NAME_SQUIGGLY_BRACKETS else null
|
element.isSquigglyBracket -> if (settings.isEnableRainbowSquigglyBrackets) NAME_SQUIGGLY_BRACKETS else null
|
||||||
element.isAngleBracket -> if (settings.isEnableRainbowAngleBrackets) NAME_ANGLE_BRACKETS else null
|
element.isAngleBracket -> if (settings.isEnableRainbowAngleBrackets) NAME_ANGLE_BRACKETS else null
|
||||||
else -> NAME_ROUND_BRACKETS
|
else -> NAME_ROUND_BRACKETS
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
return getRainbowColorByLevel(colorsScheme, rainbowName, level)
|
return getRainbowColorByLevel(colorsScheme, rainbowName, level)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHighlightInfo(colorsScheme: TextAttributesScheme, element: PsiElement, level: Int)
|
fun getHighlightInfo(colorsScheme: TextAttributesScheme, element: PsiElement, level: Int)
|
||||||
: HighlightInfo? = getTextAttributes(colorsScheme, element, level)
|
: HighlightInfo? = getTextAttributes(colorsScheme, element, level)
|
||||||
?.let { attr ->
|
?.let { attr ->
|
||||||
HighlightInfo
|
HighlightInfo
|
||||||
.newHighlightInfo(rainbowElement)
|
.newHighlightInfo(rainbowElement)
|
||||||
.textAttributes(attr)
|
.textAttributes(attr)
|
||||||
.range(element)
|
.range(element)
|
||||||
.create()
|
.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val KEY_HTML_CODE: TextAttributesKey by lazy { TextAttributesKey.createTextAttributesKey("HTML_CODE") }
|
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_KOTLIN_LABEL: TextAttributesKey by lazy { TextAttributesKey.createTextAttributesKey("KOTLIN_LABEL") }
|
||||||
private val KEY_MATCHED_BRACE_ATTRIBUTES: TextAttributesKey by lazy {
|
private val KEY_MATCHED_BRACE_ATTRIBUTES: TextAttributesKey by lazy {
|
||||||
TextAttributesKey.createTextAttributesKey("MATCHED_BRACE_ATTRIBUTES")
|
TextAttributesKey.createTextAttributesKey("MATCHED_BRACE_ATTRIBUTES")
|
||||||
}
|
}
|
||||||
private val KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW: TextAttributesKey by lazy {
|
private val KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW: TextAttributesKey by lazy {
|
||||||
TextAttributesKey.createTextAttributesKey("KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW")
|
TextAttributesKey.createTextAttributesKey("KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun fixHighlighting(scheme: EditorColorsScheme = EditorColorsManager.getInstance().globalScheme) {
|
fun fixHighlighting(scheme: EditorColorsScheme = EditorColorsManager.getInstance().globalScheme) {
|
||||||
// html code
|
// html code
|
||||||
scheme.setInherited(KEY_HTML_CODE, !settings.isRainbowifyHTMLInsideJS)
|
scheme.setInherited(KEY_HTML_CODE, !settings.isRainbowifyHTMLInsideJS)
|
||||||
|
|
||||||
// kotlin label
|
// kotlin label
|
||||||
val kotlinLabelColor = DEFAULT_KOTLIN_LABEL_COLOR.takeUnless { settings.isRainbowifyKotlinLabel }
|
val kotlinLabelColor = DEFAULT_KOTLIN_LABEL_COLOR.takeUnless { settings.isRainbowifyKotlinLabel }
|
||||||
val kotlinLabel = TextAttributes(kotlinLabelColor, null, null, EffectType.BOXED, Font.PLAIN)
|
val kotlinLabel = TextAttributes(kotlinLabelColor, null, null, EffectType.BOXED, Font.PLAIN)
|
||||||
scheme.setAttributes(KEY_KOTLIN_LABEL, kotlinLabel)
|
scheme.setAttributes(KEY_KOTLIN_LABEL, kotlinLabel)
|
||||||
|
|
||||||
// matched brace
|
// matched brace
|
||||||
if (settings.isOverrideMatchedBraceAttributes) {
|
if (settings.isOverrideMatchedBraceAttributes) {
|
||||||
val matchedBraceAttributes = TextAttributes(null, JBColor(0x99ccbb, 0x3b514d), null, EffectType.BOXED, Font.BOLD)
|
val matchedBraceAttributes = TextAttributes(null, JBColor(0x99ccbb, 0x3b514d), null, EffectType.BOXED, Font.BOLD)
|
||||||
scheme.setAttributes(KEY_MATCHED_BRACE_ATTRIBUTES, matchedBraceAttributes)
|
scheme.setAttributes(KEY_MATCHED_BRACE_ATTRIBUTES, matchedBraceAttributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.isRainbowifyKotlinFunctionLiteralBracesAndArrow) {
|
if (settings.isRainbowifyKotlinFunctionLiteralBracesAndArrow) {
|
||||||
scheme.setAttributes(KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW,
|
scheme.setAttributes(
|
||||||
TextAttributes(null, null, null, EffectType.BOXED, Font.BOLD))
|
KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW,
|
||||||
} else {
|
TextAttributes(null, null, null, EffectType.BOXED, Font.BOLD)
|
||||||
scheme.setAttributes(KOTLIN_FUNCTION_LITERAL_BRACES_AND_ARROW,
|
)
|
||||||
//TODO: default foregroundColor ???
|
}
|
||||||
TextAttributes(JBColor(0x89ddff, 0x89ddff), 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) {
|
private fun EditorColorsScheme.setInherited(key: TextAttributesKey, inherited: Boolean) {
|
||||||
setAttributes(key, if (inherited) AbstractColorsScheme.INHERITED_ATTRS_MARKER else TextAttributes())
|
setAttributes(key, if (inherited) AbstractColorsScheme.INHERITED_ATTRS_MARKER else TextAttributes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,35 +6,35 @@ import java.awt.Color
|
|||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
data class RainbowInfo(var level: Int, var color: Color) {
|
data class RainbowInfo(var level: Int, var color: Color) {
|
||||||
private var _startElement: WeakReference<PsiElement>? = null
|
private var _startElement: WeakReference<PsiElement>? = null
|
||||||
private var _endElement: WeakReference<PsiElement>? = null
|
private var _endElement: WeakReference<PsiElement>? = null
|
||||||
|
|
||||||
var startElement: PsiElement?
|
var startElement: PsiElement?
|
||||||
get() = _startElement?.get()
|
get() = _startElement?.get()
|
||||||
set(value) {
|
set(value) {
|
||||||
_startElement = value?.let { WeakReference(it) }
|
_startElement = value?.let { WeakReference(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val startOffset get() = startElement?.textRange?.startOffset ?: -1
|
val startOffset get() = startElement?.textRange?.startOffset ?: -1
|
||||||
|
|
||||||
var endElement: PsiElement?
|
var endElement: PsiElement?
|
||||||
get() = _endElement?.get()
|
get() = _endElement?.get()
|
||||||
set(value) {
|
set(value) {
|
||||||
_endElement = value?.let { WeakReference(it) }
|
_endElement = value?.let { WeakReference(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val endOffset get() = endElement?.textRange?.endOffset ?: -1
|
val endOffset get() = endElement?.textRange?.endOffset ?: -1
|
||||||
|
|
||||||
fun containsOffset(offset: Int): Boolean {
|
fun containsOffset(offset: Int): Boolean {
|
||||||
val startElement = startElement ?: return false
|
val startElement = startElement ?: return false
|
||||||
val endElement = endElement ?: return false
|
val endElement = endElement ?: return false
|
||||||
val startOffset = startElement.textRange.startOffset
|
val startOffset = startElement.textRange.startOffset
|
||||||
val endOffset = endElement.textRange.endOffset
|
val endOffset = endElement.textRange.endOffset
|
||||||
|
|
||||||
return offset in startOffset..endOffset
|
return offset in startOffset..endOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val RAINBOW_INFO_KEY: Key<RainbowInfo> = Key.create("RAINBOW_INFO")
|
val RAINBOW_INFO_KEY: Key<RainbowInfo> = Key.create("RAINBOW_INFO")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,97 +0,0 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets
|
|
||||||
|
|
||||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
|
||||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
|
||||||
import com.intellij.ide.plugins.PluginManagerCore
|
|
||||||
import com.intellij.ide.plugins.PluginManagerCore.isPluginInstalled
|
|
||||||
import com.intellij.ide.startup.StartupActionScriptManager
|
|
||||||
import com.intellij.ide.startup.StartupActionScriptManager.DeleteCommand
|
|
||||||
import com.intellij.notification.NotificationListener.UrlOpeningListener
|
|
||||||
import com.intellij.notification.NotificationType
|
|
||||||
import com.intellij.openapi.extensions.PluginId
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.startup.StartupActivity
|
|
||||||
|
|
||||||
|
|
||||||
class RainbowUpdateNotifyActivity : StartupActivity {
|
|
||||||
|
|
||||||
override fun runActivity(project: Project) {
|
|
||||||
removeIfInstalled()
|
|
||||||
val settings = RainbowSettings.instance
|
|
||||||
if (getPlugin()?.version != settings.version) {
|
|
||||||
settings.version = getPlugin()!!.version
|
|
||||||
if (settings.showNotificationOnUpdate) {
|
|
||||||
showUpdate(project)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removeIfInstalled() {
|
|
||||||
val pluginId = PluginId.getId("com.github.jadepeng.rainbowfart")
|
|
||||||
val isInstalled = isPluginInstalled(pluginId)
|
|
||||||
if (isInstalled) {
|
|
||||||
val pluginDescriptor = PluginManagerCore.getPlugin(pluginId)
|
|
||||||
if (pluginDescriptor != null) {
|
|
||||||
//disablePlugin(pluginId)
|
|
||||||
StartupActionScriptManager.addActionCommand(DeleteCommand(pluginDescriptor.pluginPath))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val pluginId = "izhangzhihao.rainbow.brackets"
|
|
||||||
|
|
||||||
|
|
||||||
private val updateContent: String by lazy {
|
|
||||||
//language=HTML
|
|
||||||
"""
|
|
||||||
<br/>
|
|
||||||
🌈Thank you for downloading <b><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets">Rainbow Brackets</a></b>!<br>
|
|
||||||
🎉Sponsored by <a href="https://codestream.com/?utm_source=jbmarket&utm_medium=banner&utm_campaign=jbrainbowbrackets">CodeStream</a>.<br>
|
|
||||||
👍If you find this plugin helpful, <b><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets#support-us">please support us!</a>.</b><br>
|
|
||||||
<b><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets#support-us">Donate</a></b> by <b><a href="https://opencollective.com/intellij-rainbow-brackets">OpenCollective</a></b> Or AliPay/WeChatPay to <b><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets#sponsors">become a sponsor</a>!.</b><br>
|
|
||||||
📝Check out <b><a href="https://izhangzhihao.github.io/rainbow-brackets-document/">the document</a></b> for all features of this plugin.<br>
|
|
||||||
🐛If you run into any problem, <b><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues">feel free to raise an issue</a>.</b><br>
|
|
||||||
🆕See <b><a href="${changelog()}">changelog</a></b> for more details about this update.<br>
|
|
||||||
👉Want to customize your own color scheme of Rainbow Brackets? Edit it under
|
|
||||||
<b>Settings > Editor > Color Scheme > Rainbow Brackets</b><br>
|
|
||||||
👉Tired of the bundled colors? Try out the new color generator!
|
|
||||||
<b>Settings > Other Settings > Rainbow Brackets > Use color generator</b><br>
|
|
||||||
👉Other additional features under
|
|
||||||
<b>Settings > Other Settings > Rainbow Brackets</b><br/>
|
|
||||||
Enjoy your colorful code🌈.
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun changelog(): String {
|
|
||||||
val plugin = getPlugin()
|
|
||||||
return if (plugin == null) {
|
|
||||||
"""https://github.com/izhangzhihao/intellij-rainbow-brackets/releases"""
|
|
||||||
} else {
|
|
||||||
"""https://github.com/izhangzhihao/intellij-rainbow-brackets/releases/tag/${plugin.version}"""
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPlugin(): IdeaPluginDescriptor? = PluginManagerCore.getPlugin(PluginId.getId(pluginId))
|
|
||||||
|
|
||||||
private fun updateMsg(): String {
|
|
||||||
val plugin = getPlugin()
|
|
||||||
return if (plugin == null) {
|
|
||||||
"Rainbow Brackets installed."
|
|
||||||
} else {
|
|
||||||
"Rainbow Brackets updated to ${plugin.version}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showUpdate(project: Project) {
|
|
||||||
val notification = createNotification(
|
|
||||||
updateMsg(),
|
|
||||||
updateContent,
|
|
||||||
NotificationType.INFORMATION,
|
|
||||||
UrlOpeningListener(false)
|
|
||||||
)
|
|
||||||
showFullNotification(project, notification)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,77 +17,77 @@ import com.intellij.ui.EditorNotifications
|
|||||||
import com.intellij.ui.HyperlinkLabel
|
import com.intellij.ui.HyperlinkLabel
|
||||||
|
|
||||||
class RainbowifyBanner : EditorNotifications.Provider<EditorNotificationPanel>() {
|
class RainbowifyBanner : EditorNotifications.Provider<EditorNotificationPanel>() {
|
||||||
override fun getKey(): Key<EditorNotificationPanel> = KEY
|
override fun getKey(): Key<EditorNotificationPanel> = KEY
|
||||||
|
|
||||||
override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor, project: Project): EditorNotificationPanel? {
|
override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor, project: Project): EditorNotificationPanel? {
|
||||||
|
|
||||||
if (!RainbowSettings.instance.isRainbowEnabled) {
|
if (!RainbowSettings.instance.isRainbowEnabled) {
|
||||||
if (RainbowSettings.instance.suppressDisabledCheck) return null
|
if (RainbowSettings.instance.suppressDisabledCheck) return null
|
||||||
return EditorNotificationPanel().apply {
|
return EditorNotificationPanel().apply {
|
||||||
text("Rainbow Brackets is now disabled")
|
text("Colored Brackets is now disabled")
|
||||||
icon(AllIcons.General.GearPlain)
|
icon(AllIcons.General.GearPlain)
|
||||||
createComponentActionLabel("got it, don't show again") {
|
createComponentActionLabel("got it, don't show again") {
|
||||||
RainbowSettings.instance.suppressDisabledCheck = true
|
RainbowSettings.instance.suppressDisabledCheck = true
|
||||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
createComponentActionLabel("enable Rainbow Brackets") {
|
createComponentActionLabel("enable Colored Brackets") {
|
||||||
RainbowSettings.instance.isRainbowEnabled = true
|
RainbowSettings.instance.isRainbowEnabled = true
|
||||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val psiFile = file.toPsiFile(project)
|
val psiFile = file.toPsiFile(project)
|
||||||
if (psiFile != null && !checkForBigFile(psiFile)) {
|
if (psiFile != null && !checkForBigFile(psiFile)) {
|
||||||
if (RainbowSettings.instance.suppressBigFileCheck) return null
|
if (RainbowSettings.instance.suppressBigFileCheck) return null
|
||||||
return EditorNotificationPanel().apply {
|
return EditorNotificationPanel().apply {
|
||||||
text("Rainbowify is disabled for files > " + RainbowSettings.instance.bigFilesLinesThreshold + " lines")
|
text("Rainbowify is disabled for files > " + RainbowSettings.instance.bigFilesLinesThreshold + " lines")
|
||||||
icon(AllIcons.General.InspectionsEye)
|
icon(AllIcons.General.InspectionsEye)
|
||||||
createComponentActionLabel("got it, don't show again") {
|
createComponentActionLabel("got it, don't show again") {
|
||||||
RainbowSettings.instance.suppressBigFileCheck = true
|
RainbowSettings.instance.suppressBigFileCheck = true
|
||||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
createComponentActionLabel("open settings") {
|
createComponentActionLabel("open settings") {
|
||||||
ShowSettingsUtilImpl.showSettingsDialog(project, RainbowConfigurable.ID, "")
|
ShowSettingsUtilImpl.showSettingsDialog(project, RainbowConfigurable.ID, "")
|
||||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
RainbowSettings.instance.languageBlacklist.contains(file.fileType.name) ||
|
RainbowSettings.instance.languageBlacklist.contains(file.fileType.name) ||
|
||||||
RainbowSettings.instance.languageBlacklist.contains(memoizedFileExtension(file.name))
|
RainbowSettings.instance.languageBlacklist.contains(memoizedFileExtension(file.name))
|
||||||
) {
|
) {
|
||||||
if (RainbowSettings.instance.suppressBlackListCheck) return null
|
if (RainbowSettings.instance.suppressBlackListCheck) return null
|
||||||
return EditorNotificationPanel().apply {
|
return EditorNotificationPanel().apply {
|
||||||
text("Rainbowify is disabled because the language/file extension is in the black list")
|
text("Rainbowify is disabled because the language/file extension is in the black list")
|
||||||
icon(AllIcons.General.InspectionsEye)
|
icon(AllIcons.General.InspectionsEye)
|
||||||
|
|
||||||
createComponentActionLabel("got it, don't show again") {
|
createComponentActionLabel("got it, don't show again") {
|
||||||
RainbowSettings.instance.suppressBlackListCheck = true
|
RainbowSettings.instance.suppressBlackListCheck = true
|
||||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
createComponentActionLabel("open setting") {
|
createComponentActionLabel("open setting") {
|
||||||
ShowSettingsUtilImpl.showSettingsDialog(project, RainbowConfigurable.ID, "")
|
ShowSettingsUtilImpl.showSettingsDialog(project, RainbowConfigurable.ID, "")
|
||||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val KEY = Key.create<EditorNotificationPanel>("RainbowifyBanner")
|
private val KEY = Key.create<EditorNotificationPanel>("RainbowifyBanner")
|
||||||
|
|
||||||
fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
|
fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
|
||||||
val label: Ref<HyperlinkLabel> = Ref.create()
|
val label: Ref<HyperlinkLabel> = Ref.create()
|
||||||
label.set(createActionLabel(labelText) {
|
label.set(createActionLabel(labelText) {
|
||||||
callback(label.get())
|
callback(label.get())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,9 @@ import java.awt.Color
|
|||||||
val mapper: ObjectMapper by lazy { jacksonObjectMapper() }
|
val mapper: ObjectMapper by lazy { jacksonObjectMapper() }
|
||||||
|
|
||||||
fun randomColor(options: String): Color {
|
fun randomColor(options: String): Color {
|
||||||
val ops: Map<String, String> = mapper.readValue(options)
|
val ops: Map<String, String> = mapper.readValue(options)
|
||||||
return com.github.izhangzhihao.rainbow.brackets.color.randomColor(
|
return com.github.izhangzhihao.rainbow.brackets.color.randomColor(
|
||||||
fromString(ops.getOrDefault("hue", "random")),
|
fromString(ops.getOrDefault("hue", "random")),
|
||||||
Luminosity.valueOf(ops.getOrDefault("luminosity", "random"))
|
Luminosity.valueOf(ops.getOrDefault("luminosity", "random"))
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -20,77 +20,81 @@ import java.awt.event.KeyEvent
|
|||||||
|
|
||||||
abstract class AbstractScopeHighlightingAction : AnAction() {
|
abstract class AbstractScopeHighlightingAction : AnAction() {
|
||||||
|
|
||||||
final override fun update(e: AnActionEvent) {
|
final override fun update(e: AnActionEvent) {
|
||||||
e.presentation.isEnabledAndVisible = e.editor.let { it != null && it !is TextComponentEditor }
|
e.presentation.isEnabledAndVisible = e.editor.let { it != null && it !is TextComponentEditor }
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun actionPerformed(e: AnActionEvent) {
|
final override fun actionPerformed(e: AnActionEvent) {
|
||||||
val editor = e.editor ?: return
|
val editor = e.editor ?: return
|
||||||
val project = editor.project ?: return
|
val project = editor.project ?: return
|
||||||
val psiFile = project.let { PsiDocumentManager.getInstance(it).getPsiFile(editor.document) } ?: return
|
val psiFile = project.let { PsiDocumentManager.getInstance(it).getPsiFile(editor.document) } ?: return
|
||||||
val offset = editor.caretModel.offset
|
val offset = editor.caretModel.offset
|
||||||
val rainbowInfo = psiFile.findRainbowInfoAt(offset) ?: return
|
val rainbowInfo = psiFile.findRainbowInfoAt(offset) ?: return
|
||||||
val highlightManager = HighlightManager.getInstance(project)
|
val highlightManager = HighlightManager.getInstance(project)
|
||||||
val highlighters = editor.addHighlighter(highlightManager, rainbowInfo)
|
val highlighters = editor.addHighlighter(highlightManager, rainbowInfo)
|
||||||
|
|
||||||
editor.highlightingDisposer?.dispose()
|
editor.highlightingDisposer?.dispose()
|
||||||
if (highlighters.isNotEmpty()) {
|
if (highlighters.isNotEmpty()) {
|
||||||
editor.highlightingDisposer = HighlightingDisposer(editor) {
|
editor.highlightingDisposer = HighlightingDisposer(editor) {
|
||||||
editor.highlightingDisposer = null
|
editor.highlightingDisposer = null
|
||||||
highlighters.forEach { highlightManager.removeSegmentHighlighter(editor, it) }
|
highlighters.forEach { highlightManager.removeSegmentHighlighter(editor, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun Editor.addHighlighter(highlightManager: HighlightManager,
|
protected abstract fun Editor.addHighlighter(
|
||||||
rainbowInfo: RainbowInfo): Collection<RangeHighlighter>
|
highlightManager: HighlightManager,
|
||||||
|
rainbowInfo: RainbowInfo,
|
||||||
|
): Collection<RangeHighlighter>
|
||||||
|
|
||||||
private class HighlightingDisposer(private val editor: Editor,
|
private class HighlightingDisposer(
|
||||||
private val disposeAction: () -> Unit) : KeyAdapter(), FocusListener {
|
private val editor: Editor,
|
||||||
|
private val disposeAction: () -> Unit,
|
||||||
|
) : KeyAdapter(), FocusListener {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
editor.contentComponent.let {
|
editor.contentComponent.let {
|
||||||
it.addFocusListener(this)
|
it.addFocusListener(this)
|
||||||
it.addKeyListener(this)
|
it.addKeyListener(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
disposeAction()
|
disposeAction()
|
||||||
editor.contentComponent.let {
|
editor.contentComponent.let {
|
||||||
it.removeFocusListener(this)
|
it.removeFocusListener(this)
|
||||||
it.removeKeyListener(this)
|
it.removeKeyListener(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun focusGained(e: FocusEvent) = Unit
|
override fun focusGained(e: FocusEvent) = Unit
|
||||||
override fun focusLost(e: FocusEvent) = Unit
|
override fun focusLost(e: FocusEvent) = Unit
|
||||||
override fun keyReleased(e: KeyEvent) = Unit
|
override fun keyReleased(e: KeyEvent) = Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val HIGHLIGHTING_DISPOSER_KEY: Key<HighlightingDisposer> = Key.create("HIGHLIGHTING_DISPOSER_KEY")
|
private val HIGHLIGHTING_DISPOSER_KEY: Key<HighlightingDisposer> = Key.create("HIGHLIGHTING_DISPOSER_KEY")
|
||||||
|
|
||||||
private var Editor.highlightingDisposer: HighlightingDisposer?
|
private var Editor.highlightingDisposer: HighlightingDisposer?
|
||||||
get() = HIGHLIGHTING_DISPOSER_KEY[this]
|
get() = HIGHLIGHTING_DISPOSER_KEY[this]
|
||||||
set(value) {
|
set(value) {
|
||||||
HIGHLIGHTING_DISPOSER_KEY[this] = value
|
HIGHLIGHTING_DISPOSER_KEY[this] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
private val AnActionEvent.editor: Editor? get() = CommonDataKeys.EDITOR.getData(dataContext)
|
private val AnActionEvent.editor: Editor? get() = CommonDataKeys.EDITOR.getData(dataContext)
|
||||||
|
|
||||||
private fun PsiElement.getRainbowInfo(offset: Int): RainbowInfo? {
|
private fun PsiElement.getRainbowInfo(offset: Int): RainbowInfo? {
|
||||||
return RainbowInfo.RAINBOW_INFO_KEY[this]?.takeIf { it.containsOffset(offset) }
|
return RainbowInfo.RAINBOW_INFO_KEY[this]?.takeIf { it.containsOffset(offset) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PsiFile.findRainbowInfoAt(offset: Int): RainbowInfo? {
|
private fun PsiFile.findRainbowInfoAt(offset: Int): RainbowInfo? {
|
||||||
var element = findElementAt(offset)
|
var element = findElementAt(offset)
|
||||||
while (element != null) {
|
while (element != null) {
|
||||||
element.getRainbowInfo(offset)?.let { return it }
|
element.getRainbowInfo(offset)?.let { return it }
|
||||||
element = element.parent
|
element = element.parent
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,6 @@ package com.github.izhangzhihao.rainbow.brackets.action
|
|||||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||||
import com.github.izhangzhihao.rainbow.brackets.util.alphaBlend
|
import com.github.izhangzhihao.rainbow.brackets.util.alphaBlend
|
||||||
import com.github.izhangzhihao.rainbow.brackets.util.create
|
|
||||||
import com.intellij.codeInsight.highlighting.HighlightManager
|
import com.intellij.codeInsight.highlighting.HighlightManager
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||||
@ -11,26 +10,30 @@ import com.intellij.openapi.editor.markup.EffectType
|
|||||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||||
import com.intellij.openapi.editor.markup.TextAttributes
|
import com.intellij.openapi.editor.markup.TextAttributes
|
||||||
import java.awt.Font
|
import java.awt.Font
|
||||||
import java.util.*
|
import java.util.LinkedList
|
||||||
|
|
||||||
|
|
||||||
class ScopeHighlightingAction : AbstractScopeHighlightingAction() {
|
class ScopeHighlightingAction : AbstractScopeHighlightingAction() {
|
||||||
|
|
||||||
override fun Editor.addHighlighter(highlightManager: HighlightManager,
|
override fun Editor.addHighlighter(
|
||||||
rainbowInfo: RainbowInfo): Collection<RangeHighlighter> {
|
highlightManager: HighlightManager,
|
||||||
val defaultBackground = EditorColorsManager.getInstance().globalScheme.defaultBackground
|
rainbowInfo: RainbowInfo,
|
||||||
val background = rainbowInfo.color.alphaBlend(defaultBackground, 0.2f)
|
): Collection<RangeHighlighter> {
|
||||||
val attributes = TextAttributes(null, background, rainbowInfo.color, EffectType.BOXED, Font.PLAIN)
|
val defaultBackground = EditorColorsManager.getInstance().globalScheme.defaultBackground
|
||||||
val highlighters = LinkedList<RangeHighlighter>()
|
val background = rainbowInfo.color.alphaBlend(defaultBackground, 0.2f)
|
||||||
highlightManager.addRangeHighlight(this,
|
val attributes = TextAttributes(null, background, rainbowInfo.color, EffectType.BOXED, Font.PLAIN)
|
||||||
rainbowInfo.startOffset,
|
val highlighters = LinkedList<RangeHighlighter>()
|
||||||
rainbowInfo.endOffset,
|
highlightManager.addRangeHighlight(
|
||||||
attributes, //create("ScopeHighlightingAction", attributes),
|
this,
|
||||||
false, //hideByTextChange
|
rainbowInfo.startOffset,
|
||||||
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
rainbowInfo.endOffset,
|
||||||
highlighters)
|
attributes, //create("ScopeHighlightingAction", attributes),
|
||||||
|
false, //hideByTextChange
|
||||||
|
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
||||||
|
highlighters
|
||||||
|
)
|
||||||
|
|
||||||
return highlighters
|
return highlighters
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,7 +3,6 @@ package com.github.izhangzhihao.rainbow.brackets.action
|
|||||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||||
import com.github.izhangzhihao.rainbow.brackets.util.alphaBlend
|
import com.github.izhangzhihao.rainbow.brackets.util.alphaBlend
|
||||||
import com.github.izhangzhihao.rainbow.brackets.util.create
|
|
||||||
import com.intellij.codeInsight.highlighting.HighlightManager
|
import com.intellij.codeInsight.highlighting.HighlightManager
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||||
@ -12,42 +11,48 @@ import com.intellij.openapi.editor.markup.RangeHighlighter
|
|||||||
import com.intellij.openapi.editor.markup.TextAttributes
|
import com.intellij.openapi.editor.markup.TextAttributes
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.awt.Font
|
import java.awt.Font
|
||||||
import java.util.*
|
import java.util.LinkedList
|
||||||
|
|
||||||
class ScopeOutsideHighlightingRestrainAction : AbstractScopeHighlightingAction() {
|
class ScopeOutsideHighlightingRestrainAction : AbstractScopeHighlightingAction() {
|
||||||
|
|
||||||
override fun Editor.addHighlighter(highlightManager: HighlightManager,
|
override fun Editor.addHighlighter(
|
||||||
rainbowInfo: RainbowInfo): Collection<RangeHighlighter> {
|
highlightManager: HighlightManager,
|
||||||
val defaultBackground = EditorColorsManager.getInstance().globalScheme.defaultBackground
|
rainbowInfo: RainbowInfo,
|
||||||
val background = Color.GRAY.alphaBlend(defaultBackground, 0.05f)
|
): Collection<RangeHighlighter> {
|
||||||
val foreground = Color.GRAY.alphaBlend(defaultBackground, 0.55f)
|
val defaultBackground = EditorColorsManager.getInstance().globalScheme.defaultBackground
|
||||||
val attributes = TextAttributes(foreground, background, background, EffectType.BOXED, Font.PLAIN)
|
val background = Color.GRAY.alphaBlend(defaultBackground, 0.05f)
|
||||||
val highlighters = LinkedList<RangeHighlighter>()
|
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
|
val startOffset = rainbowInfo.startOffset
|
||||||
if (startOffset > 0) {
|
if (startOffset > 0) {
|
||||||
highlightManager.addRangeHighlight(this,
|
highlightManager.addRangeHighlight(
|
||||||
0,
|
this,
|
||||||
startOffset,
|
0,
|
||||||
attributes, //create("ScopeOutsideHighlightingRestrainAction", attributes),
|
startOffset,
|
||||||
false, //hideByTextChange
|
attributes, //create("ScopeOutsideHighlightingRestrainAction", attributes),
|
||||||
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
false, //hideByTextChange
|
||||||
highlighters)
|
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
||||||
}
|
highlighters
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val endOffset = rainbowInfo.endOffset
|
val endOffset = rainbowInfo.endOffset
|
||||||
val lastOffset = document.textLength
|
val lastOffset = document.textLength
|
||||||
if (endOffset < lastOffset) {
|
if (endOffset < lastOffset) {
|
||||||
highlightManager.addRangeHighlight(this,
|
highlightManager.addRangeHighlight(
|
||||||
endOffset,
|
this,
|
||||||
lastOffset,
|
endOffset,
|
||||||
attributes, //create("ScopeOutsideHighlightingRestrainAction", attributes),
|
lastOffset,
|
||||||
false, //hideByTextChange
|
attributes, //create("ScopeOutsideHighlightingRestrainAction", attributes),
|
||||||
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
false, //hideByTextChange
|
||||||
highlighters)
|
RainbowSettings.instance.pressAnyKeyToRemoveTheHighlightingEffects, //hideByAnyKey
|
||||||
}
|
highlighters
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return highlighters
|
return highlighters
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -12,67 +12,87 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
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
|
import java.awt.Font
|
||||||
|
|
||||||
|
|
||||||
class KotlinLabelAnnotator : Annotator {
|
class KotlinLabelAnnotator : Annotator {
|
||||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||||
if (!RainbowSettings.instance.isRainbowifyKotlinLabel) {
|
if (!RainbowSettings.instance.isRainbowifyKotlinLabel) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val target: PsiElement
|
val target: PsiElement
|
||||||
var refElement: PsiElement?
|
var refElement: PsiElement?
|
||||||
when (element) {
|
when (element) {
|
||||||
is KtLabelReferenceExpression -> {
|
is KtLabelReferenceExpression -> {
|
||||||
if ((element.lastChild as? LeafPsiElement)?.elementType == KtTokens.AT) {
|
if ((element.lastChild as? LeafPsiElement)?.elementType == KtTokens.AT) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
target = element
|
target = element
|
||||||
refElement = try {
|
refElement = try {
|
||||||
element.reference?.resolve()
|
element.reference?.resolve()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
refElement = when (refElement) {
|
refElement = when (refElement) {
|
||||||
is KtBlockExpression,
|
is KtBlockExpression,
|
||||||
is KtFunctionLiteral -> refElement
|
is KtFunctionLiteral,
|
||||||
is KtFunction -> refElement.lastChild.takeIf { it is KtBlockExpression }
|
-> refElement
|
||||||
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
|
is KtFunction -> refElement.lastChild.takeIf { it is KtBlockExpression }
|
||||||
.let { RainbowInfo.RAINBOW_INFO_KEY[it]?.color ?: RainbowHighlighter.DEFAULT_KOTLIN_LABEL_COLOR }
|
is KtClass -> refElement.lastChild.takeIf { it is KtClassBody }
|
||||||
.let {
|
is KtCallExpression,
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
is KtLambdaExpression,
|
||||||
.range(target)
|
-> PsiTreeUtil.findChildOfType(refElement, KtFunctionLiteral::class.java)
|
||||||
.textAttributes(com.github.izhangzhihao.rainbow.brackets.util.create(
|
|
||||||
"rainbow-kotlin-label",
|
else -> null
|
||||||
TextAttributes(it, null, null, EffectType.BOXED, Font.PLAIN)
|
}
|
||||||
))
|
}
|
||||||
.create()
|
|
||||||
}
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -13,19 +13,19 @@ import java.awt.Font
|
|||||||
|
|
||||||
|
|
||||||
class KotlinLambdaExpressionArrowAnnotator : Annotator {
|
class KotlinLambdaExpressionArrowAnnotator : Annotator {
|
||||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||||
if ((element as? LeafPsiElement)?.elementType == KtTokens.ARROW) {
|
if ((element as? LeafPsiElement)?.elementType == KtTokens.ARROW) {
|
||||||
RainbowInfo.RAINBOW_INFO_KEY[element.parent]?.color?.let {
|
RainbowInfo.RAINBOW_INFO_KEY[element.parent]?.color?.let {
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
.range(element)
|
.range(element)
|
||||||
.textAttributes(
|
.textAttributes(
|
||||||
com.github.izhangzhihao.rainbow.brackets.util.create(
|
com.github.izhangzhihao.rainbow.brackets.util.create(
|
||||||
"rainbow-kotlin-arrow",
|
"rainbow-kotlin-arrow",
|
||||||
TextAttributes(it, null, null, EffectType.BOXED, Font.PLAIN)
|
TextAttributes(it, null, null, EffectType.BOXED, Font.PLAIN)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.create()
|
.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,99 +17,106 @@ import com.intellij.psi.PsiFile
|
|||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
|
|
||||||
class RainbowAnnotator : Annotator {
|
class RainbowAnnotator : Annotator {
|
||||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||||
if (settings.isRainbowEnabled && element is LeafPsiElement) {
|
if (settings.isRainbowEnabled && element is LeafPsiElement) {
|
||||||
if (!settings.applyColorsOfRoundForAllBrackets) {
|
if (!settings.applyColorsOfRoundForAllBrackets) {
|
||||||
if (settings.isEnableRainbowRoundBrackets) annotateUtil(element, holder, "(", ")", NAME_ROUND_BRACKETS)
|
if (settings.isEnableRainbowRoundBrackets) annotateUtil(element, holder, "(", ")", NAME_ROUND_BRACKETS)
|
||||||
if (settings.isEnableRainbowSquareBrackets) annotateUtil(element, holder, "[", "]", NAME_SQUARE_BRACKETS)
|
if (settings.isEnableRainbowSquareBrackets) annotateUtil(element, holder, "[", "]", NAME_SQUARE_BRACKETS)
|
||||||
if (settings.isEnableRainbowSquigglyBrackets) annotateUtil(element, holder, "{", "}", NAME_SQUIGGLY_BRACKETS)
|
if (settings.isEnableRainbowSquigglyBrackets) annotateUtil(element, holder, "{", "}", NAME_SQUIGGLY_BRACKETS)
|
||||||
if (settings.isEnableRainbowAngleBrackets) annotateUtil(element, holder, "<", ">", NAME_ANGLE_BRACKETS)
|
if (settings.isEnableRainbowAngleBrackets) annotateUtil(element, holder, "<", ">", NAME_ANGLE_BRACKETS)
|
||||||
} else {
|
}
|
||||||
if (settings.isEnableRainbowRoundBrackets) annotateUtil(element, holder, "(", ")", NAME_ROUND_BRACKETS)
|
else {
|
||||||
if (settings.isEnableRainbowSquareBrackets) annotateUtil(element, holder, "[", "]", NAME_ROUND_BRACKETS)
|
if (settings.isEnableRainbowRoundBrackets) annotateUtil(element, holder, "(", ")", NAME_ROUND_BRACKETS)
|
||||||
if (settings.isEnableRainbowSquigglyBrackets) annotateUtil(element, holder, "{", "}", NAME_ROUND_BRACKETS)
|
if (settings.isEnableRainbowSquareBrackets) annotateUtil(element, holder, "[", "]", NAME_ROUND_BRACKETS)
|
||||||
if (settings.isEnableRainbowAngleBrackets) 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 {
|
object RainbowUtils {
|
||||||
|
|
||||||
private val leftBracketsSet = setOf("(", "[", "{", "<")
|
private val leftBracketsSet = setOf("(", "[", "{", "<")
|
||||||
private val rightBracketsSet = setOf(")", "]", "}", ">")
|
private val rightBracketsSet = setOf(")", "]", "}", ">")
|
||||||
|
|
||||||
val settings = RainbowSettings.instance
|
val settings = RainbowSettings.instance
|
||||||
|
|
||||||
private tailrec fun iterateChildren(
|
private tailrec fun iterateChildren(
|
||||||
LEFT: String,
|
LEFT: String,
|
||||||
RIGHT: String,
|
RIGHT: String,
|
||||||
currentNode: PsiElement,
|
currentNode: PsiElement,
|
||||||
currentLevel: Int,
|
currentLevel: Int,
|
||||||
currentChild: PsiElement
|
currentChild: PsiElement,
|
||||||
): Int {
|
): Int {
|
||||||
val calculatedLevel = if (currentChild is LeafPsiElement) {
|
val calculatedLevel = if (currentChild is LeafPsiElement) {
|
||||||
//Using `currentChild.elementType.toString()` if we didn't want add more dependencies.
|
//Using `currentChild.elementType.toString()` if we didn't want add more dependencies.
|
||||||
if (!settings.cycleCountOnAllBrackets) {
|
if (!settings.cycleCountOnAllBrackets) {
|
||||||
when (currentChild.text) {
|
when (currentChild.text) {
|
||||||
LEFT -> currentLevel + 1
|
LEFT -> currentLevel + 1
|
||||||
RIGHT -> currentLevel - 1
|
RIGHT -> currentLevel - 1
|
||||||
else -> currentLevel
|
else -> currentLevel
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
when {
|
else {
|
||||||
leftBracketsSet.contains(currentChild.text) -> currentLevel + 1
|
when {
|
||||||
rightBracketsSet.contains(currentChild.text) -> currentLevel - 1
|
leftBracketsSet.contains(currentChild.text) -> currentLevel + 1
|
||||||
else -> currentLevel
|
rightBracketsSet.contains(currentChild.text) -> currentLevel - 1
|
||||||
}
|
else -> currentLevel
|
||||||
}
|
}
|
||||||
} else currentLevel
|
}
|
||||||
|
}
|
||||||
|
else currentLevel
|
||||||
|
|
||||||
return if ((currentChild != currentNode) && (currentChild != currentNode.parent.lastChild))
|
return if ((currentChild != currentNode) && (currentChild != currentNode.parent.lastChild))
|
||||||
iterateChildren(LEFT, RIGHT, currentNode, calculatedLevel, currentChild.nextSibling)
|
iterateChildren(LEFT, RIGHT, currentNode, calculatedLevel, currentChild.nextSibling)
|
||||||
else
|
else
|
||||||
calculatedLevel
|
calculatedLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
private tailrec fun iterateParents(
|
private tailrec fun iterateParents(
|
||||||
LEFT: String,
|
LEFT: String,
|
||||||
RIGHT: String,
|
RIGHT: String,
|
||||||
currentNode: PsiElement,
|
currentNode: PsiElement,
|
||||||
currentLevel: Int
|
currentLevel: Int,
|
||||||
): Int = if (currentNode.parent !is PsiFile) {
|
): Int = if (currentNode.parent !is PsiFile) {
|
||||||
val calculatedLevel = iterateChildren(LEFT, RIGHT, currentNode, currentLevel, currentNode.parent.firstChild)
|
val calculatedLevel = iterateChildren(LEFT, RIGHT, currentNode, currentLevel, currentNode.parent.firstChild)
|
||||||
iterateParents(LEFT, RIGHT, currentNode.parent, calculatedLevel)
|
iterateParents(LEFT, RIGHT, currentNode.parent, calculatedLevel)
|
||||||
} else currentLevel
|
}
|
||||||
|
else currentLevel
|
||||||
|
|
||||||
private fun getBracketLevel(element: LeafPsiElement, LEFT: String, RIGHT: String): Int {
|
private fun getBracketLevel(element: LeafPsiElement, LEFT: String, RIGHT: String): Int {
|
||||||
//Using `element.elementType.toString()` if we didn't want add more dependencies.
|
//Using `element.elementType.toString()` if we didn't want add more dependencies.
|
||||||
val startLevel = if (element.text == RIGHT) 0 else -1
|
val startLevel = if (element.text == RIGHT) 0 else -1
|
||||||
return iterateParents(LEFT, RIGHT, element, startLevel)
|
return iterateParents(LEFT, RIGHT, element, startLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun annotateUtil(element: LeafPsiElement, holder: AnnotationHolder,
|
fun annotateUtil(
|
||||||
LEFT: String, RIGHT: String, rainbowName: String) {
|
element: LeafPsiElement, holder: AnnotationHolder,
|
||||||
//Using `element.elementType.toString()` if we didn't want add more dependencies.
|
LEFT: String, RIGHT: String, rainbowName: String,
|
||||||
val level = when (element.text) {
|
) {
|
||||||
LEFT, RIGHT -> getBracketLevel(element, LEFT, RIGHT)
|
//Using `element.elementType.toString()` if we didn't want add more dependencies.
|
||||||
else -> -1
|
val level = when (element.text) {
|
||||||
}
|
LEFT, RIGHT -> getBracketLevel(element, LEFT, RIGHT)
|
||||||
val scheme = EditorColorsManager.getInstance().globalScheme
|
else -> -1
|
||||||
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
}
|
||||||
if (level >= 1) {
|
val scheme = EditorColorsManager.getInstance().globalScheme
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
||||||
.range(element.psi)
|
if (level >= 1) {
|
||||||
.textAttributes(getRainbowColorByLevel(scheme, rainbowName, level))
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
.create()
|
.range(element.psi)
|
||||||
}
|
.textAttributes(getRainbowColorByLevel(scheme, rainbowName, level))
|
||||||
} else {
|
.create()
|
||||||
if (level >= 0) {
|
}
|
||||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
}
|
||||||
.range(element.psi)
|
else {
|
||||||
.textAttributes(getRainbowColorByLevel(scheme, rainbowName, level))
|
if (level >= 0) {
|
||||||
.create()
|
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
|
||||||
}
|
.range(element.psi)
|
||||||
}
|
.textAttributes(getRainbowColorByLevel(scheme, rainbowName, level))
|
||||||
}
|
.create()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,106 +3,106 @@ package com.github.izhangzhihao.rainbow.brackets.color
|
|||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
enum class Color(val hueRange: Pair<Int, Int>, val lowerBounds: List<Pair<Int, Int>>) {
|
enum class Color(val hueRange: Pair<Int, Int>, val lowerBounds: List<Pair<Int, Int>>) {
|
||||||
monochrome(
|
monochrome(
|
||||||
Pair(-1, -1),
|
Pair(-1, -1),
|
||||||
listOf(Pair(0, 0), Pair(100, 0))
|
listOf(Pair(0, 0), Pair(100, 0))
|
||||||
),
|
),
|
||||||
red(
|
red(
|
||||||
Pair(-26, 18),
|
Pair(-26, 18),
|
||||||
listOf(
|
listOf(
|
||||||
Pair(20, 100),
|
Pair(20, 100),
|
||||||
Pair(30, 92),
|
Pair(30, 92),
|
||||||
Pair(40, 89),
|
Pair(40, 89),
|
||||||
Pair(50, 85),
|
Pair(50, 85),
|
||||||
Pair(60, 78),
|
Pair(60, 78),
|
||||||
Pair(70, 70),
|
Pair(70, 70),
|
||||||
Pair(80, 60),
|
Pair(80, 60),
|
||||||
Pair(90, 55),
|
Pair(90, 55),
|
||||||
Pair(100, 50)
|
Pair(100, 50)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
orange(
|
orange(
|
||||||
Pair(18, 46),
|
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))
|
listOf(Pair(20, 100), Pair(30, 93), Pair(40, 88), Pair(50, 86), Pair(60, 85), Pair(70, 70), Pair(100, 70))
|
||||||
),
|
),
|
||||||
yellow(
|
yellow(
|
||||||
Pair(46, 62),
|
Pair(46, 62),
|
||||||
listOf(
|
listOf(
|
||||||
Pair(25, 100),
|
Pair(25, 100),
|
||||||
Pair(40, 94),
|
Pair(40, 94),
|
||||||
Pair(50, 89),
|
Pair(50, 89),
|
||||||
Pair(60, 86),
|
Pair(60, 86),
|
||||||
Pair(70, 84),
|
Pair(70, 84),
|
||||||
Pair(80, 82),
|
Pair(80, 82),
|
||||||
Pair(90, 80),
|
Pair(90, 80),
|
||||||
Pair(100, 75)
|
Pair(100, 75)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
green(
|
green(
|
||||||
Pair(62, 178),
|
Pair(62, 178),
|
||||||
listOf(
|
listOf(
|
||||||
Pair(30, 100),
|
Pair(30, 100),
|
||||||
Pair(40, 90),
|
Pair(40, 90),
|
||||||
Pair(50, 85),
|
Pair(50, 85),
|
||||||
Pair(60, 81),
|
Pair(60, 81),
|
||||||
Pair(70, 74),
|
Pair(70, 74),
|
||||||
Pair(80, 64),
|
Pair(80, 64),
|
||||||
Pair(90, 50),
|
Pair(90, 50),
|
||||||
Pair(100, 40)
|
Pair(100, 40)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
blue(
|
blue(
|
||||||
Pair(178, 257),
|
Pair(178, 257),
|
||||||
listOf(
|
listOf(
|
||||||
Pair(20, 100),
|
Pair(20, 100),
|
||||||
Pair(30, 86),
|
Pair(30, 86),
|
||||||
Pair(40, 80),
|
Pair(40, 80),
|
||||||
Pair(50, 74),
|
Pair(50, 74),
|
||||||
Pair(60, 60),
|
Pair(60, 60),
|
||||||
Pair(70, 52),
|
Pair(70, 52),
|
||||||
Pair(80, 44),
|
Pair(80, 44),
|
||||||
Pair(90, 39),
|
Pair(90, 39),
|
||||||
Pair(100, 35)
|
Pair(100, 35)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
purple(
|
purple(
|
||||||
Pair(257, 282),
|
Pair(257, 282),
|
||||||
listOf(
|
listOf(
|
||||||
Pair(20, 100),
|
Pair(20, 100),
|
||||||
Pair(30, 87),
|
Pair(30, 87),
|
||||||
Pair(40, 79),
|
Pair(40, 79),
|
||||||
Pair(50, 70),
|
Pair(50, 70),
|
||||||
Pair(60, 65),
|
Pair(60, 65),
|
||||||
Pair(70, 59),
|
Pair(70, 59),
|
||||||
Pair(80, 52),
|
Pair(80, 52),
|
||||||
Pair(90, 45),
|
Pair(90, 45),
|
||||||
Pair(100, 42)
|
Pair(100, 42)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
pink(
|
pink(
|
||||||
Pair(282, 334),
|
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))
|
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> {
|
fun Color.saturationRange(): Pair<Int, Int> {
|
||||||
return Pair(lowerBounds.first().first, lowerBounds.last().first)
|
return Pair(lowerBounds.first().first, lowerBounds.last().first)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Color.brightnessRange(saturation: Int): Pair<Int, Int> {
|
fun Color.brightnessRange(saturation: Int): Pair<Int, Int> {
|
||||||
for (i in 0 until lowerBounds.size - 1) {
|
for (i in 0 until lowerBounds.size - 1) {
|
||||||
val s1 = lowerBounds[i].first.toFloat()
|
val s1 = lowerBounds[i].first.toFloat()
|
||||||
val v1 = lowerBounds[i].second.toFloat()
|
val v1 = lowerBounds[i].second.toFloat()
|
||||||
|
|
||||||
val s2 = lowerBounds[i + 1].first.toFloat()
|
val s2 = lowerBounds[i + 1].first.toFloat()
|
||||||
val v2 = lowerBounds[i + 1].second.toFloat()
|
val v2 = lowerBounds[i + 1].second.toFloat()
|
||||||
|
|
||||||
if (saturation.toFloat() in s1..s2) {
|
if (saturation.toFloat() in s1..s2) {
|
||||||
val m = (v2 - v1) / (s2 - s1)
|
val m = (v2 - v1) / (s2 - s1)
|
||||||
val b = v1 - m * s1
|
val b = v1 - m * s1
|
||||||
val minBrightness = m * saturation + b
|
val minBrightness = m * saturation + b
|
||||||
return Pair(floor(minBrightness).toInt(), 100)
|
return Pair(floor(minBrightness).toInt(), 100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Pair(0, 100)
|
return Pair(0, 100)
|
||||||
}
|
}
|
@ -7,17 +7,17 @@ data class NumberHue(val value: Int) : Hue()
|
|||||||
data class ColorHue(val color: Color) : Hue()
|
data class ColorHue(val color: Color) : Hue()
|
||||||
|
|
||||||
fun Hue.getHueRange(): Pair<Int, Int> {
|
fun Hue.getHueRange(): Pair<Int, Int> {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ColorHue -> color.hueRange
|
is ColorHue -> color.hueRange
|
||||||
is NumberHue -> if (value in 1..359) Pair(value, value) else Pair(0, 360)
|
is NumberHue -> if (value in 1..359) Pair(value, value) else Pair(0, 360)
|
||||||
RandomHue -> Pair(0, 360)
|
RandomHue -> Pair(0, 360)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fromString(str: String): Hue {
|
fun fromString(str: String): Hue {
|
||||||
return when {
|
return when {
|
||||||
str == "random" -> RandomHue
|
str == "random" -> RandomHue
|
||||||
str.startsWith("#") -> NumberHue(Integer.parseInt(str.replaceFirst("#", ""), 16))
|
str.startsWith("#") -> NumberHue(Integer.parseInt(str.replaceFirst("#", ""), 16))
|
||||||
else -> ColorHue(Color.valueOf(str))
|
else -> ColorHue(Color.valueOf(str))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets.color
|
package com.github.izhangzhihao.rainbow.brackets.color
|
||||||
|
|
||||||
enum class Luminosity {
|
enum class Luminosity {
|
||||||
random,
|
random,
|
||||||
bright,
|
bright,
|
||||||
light,
|
light,
|
||||||
dark
|
dark
|
||||||
}
|
}
|
@ -8,111 +8,116 @@ import kotlin.random.Random
|
|||||||
* Generate a single random color with specified (or random) hue and luminosity.
|
* Generate a single random color with specified (or random) hue and luminosity.
|
||||||
*/
|
*/
|
||||||
fun randomColor(
|
fun randomColor(
|
||||||
hue: Hue = RandomHue,
|
hue: Hue = RandomHue,
|
||||||
luminosity: Luminosity = Luminosity.random,
|
luminosity: Luminosity = Luminosity.random,
|
||||||
): java.awt.Color {
|
): java.awt.Color {
|
||||||
|
|
||||||
// First we pick a hue (H)
|
// First we pick a hue (H)
|
||||||
val hueValue = pickHue(hue)
|
val hueValue = pickHue(hue)
|
||||||
|
|
||||||
// Then use H to determine saturation (S)
|
// Then use H to determine saturation (S)
|
||||||
val saturation = pickSaturation(hueValue, hue, luminosity)
|
val saturation = pickSaturation(hueValue, hue, luminosity)
|
||||||
|
|
||||||
// Then use S and H to determine brightness (B)
|
// Then use S and H to determine brightness (B)
|
||||||
val brightness = pickBrightness(hueValue, hue, saturation, luminosity)
|
val brightness = pickBrightness(hueValue, hue, saturation, luminosity)
|
||||||
|
|
||||||
return toColor(hueValue, saturation, brightness)
|
return toColor(hueValue, saturation, brightness)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pickHue(hue: Hue): Int {
|
private fun pickHue(hue: Hue): Int {
|
||||||
val hueRange = hue.getHueRange()
|
val hueRange = hue.getHueRange()
|
||||||
var hueValue = randomWithin(hueRange)
|
var hueValue = randomWithin(hueRange)
|
||||||
// Instead of storing red as two separate ranges,
|
// Instead of storing red as two separate ranges,
|
||||||
// we group them, using negative numbers
|
// we group them, using negative numbers
|
||||||
if (hueValue < 0) {
|
if (hueValue < 0) {
|
||||||
hueValue += 360
|
hueValue += 360
|
||||||
}
|
}
|
||||||
return hueValue
|
return hueValue
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pickSaturation(hueValue: Int, hue: Hue, luminosity: Luminosity): Int {
|
private fun pickSaturation(hueValue: Int, hue: Hue, luminosity: Luminosity): Int {
|
||||||
if (hue == ColorHue(Color.monochrome)) {
|
if (hue == ColorHue(Color.monochrome)) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val color: Color = matchColor(hueValue, hue)
|
val color: Color = matchColor(hueValue, hue)
|
||||||
|
|
||||||
val sMin = color.saturationRange().first
|
val sMin = color.saturationRange().first
|
||||||
val sMax = color.saturationRange().second
|
val sMax = color.saturationRange().second
|
||||||
|
|
||||||
return when (luminosity) {
|
return when (luminosity) {
|
||||||
Luminosity.random -> randomWithin(Pair(0, 100))
|
Luminosity.random -> randomWithin(Pair(0, 100))
|
||||||
Luminosity.bright -> randomWithin(Pair(55, sMax))
|
Luminosity.bright -> randomWithin(Pair(55, sMax))
|
||||||
Luminosity.light -> randomWithin(Pair(sMin, 55))
|
Luminosity.light -> randomWithin(Pair(sMin, 55))
|
||||||
Luminosity.dark -> randomWithin(Pair(sMax - 10, sMax))
|
Luminosity.dark -> randomWithin(Pair(sMax - 10, sMax))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pickBrightness(hueValue: Int, hue: Hue, saturation: Int, luminosity: Luminosity): Int {
|
private fun pickBrightness(hueValue: Int, hue: Hue, saturation: Int, luminosity: Luminosity): Int {
|
||||||
val color: Color = matchColor(hueValue, hue)
|
val color: Color = matchColor(hueValue, hue)
|
||||||
|
|
||||||
val bMin = color.brightnessRange(saturation).first
|
val bMin = color.brightnessRange(saturation).first
|
||||||
val bMax = color.brightnessRange(saturation).second
|
val bMax = color.brightnessRange(saturation).second
|
||||||
|
|
||||||
return when (luminosity) {
|
return when (luminosity) {
|
||||||
Luminosity.random -> randomWithin(Pair(50, 100)) // I set this to 50 arbitrarily, they look more attractive
|
Luminosity.random -> randomWithin(Pair(50, 100)) // I set this to 50 arbitrarily, they look more attractive
|
||||||
Luminosity.bright -> randomWithin(Pair(bMin, bMax))
|
Luminosity.bright -> randomWithin(Pair(bMin, bMax))
|
||||||
Luminosity.light -> randomWithin(Pair((bMax + bMin) / 2, bMax))
|
Luminosity.light -> randomWithin(Pair((bMax + bMin) / 2, bMax))
|
||||||
Luminosity.dark -> randomWithin(Pair(bMin, bMin + 20))
|
Luminosity.dark -> randomWithin(Pair(bMin, bMin + 20))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toColor(hueValue: Int, saturation: Int, brightness: Int): java.awt.Color {
|
private fun toColor(hueValue: Int, saturation: Int, brightness: Int): java.awt.Color {
|
||||||
val rgb = HSVtoRGB(hueValue, saturation, brightness)
|
val rgb = HSVtoRGB(hueValue, saturation, brightness)
|
||||||
return java.awt.Color(rgb.first, rgb.second, rgb.third)
|
return java.awt.Color(rgb.first, rgb.second, rgb.third)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun HSVtoRGB(hueValue: Int, saturation: Int, brightness: Int): Triple<Int, Int, Int> {
|
private fun HSVtoRGB(hueValue: Int, saturation: Int, brightness: Int): Triple<Int, Int, Int> {
|
||||||
// This doesn't work for the values of 0 and 360
|
// This doesn't work for the values of 0 and 360
|
||||||
// Here's the hacky fix
|
// Here's the hacky fix
|
||||||
// Rebase the h,s,v values
|
// Rebase the h,s,v values
|
||||||
val h: Float = hueValue.coerceIn(1, 359) / 360f
|
val h: Float = hueValue.coerceIn(1, 359) / 360f
|
||||||
val s = saturation / 100f
|
val s = saturation / 100f
|
||||||
val v = brightness / 100f
|
val v = brightness / 100f
|
||||||
|
|
||||||
val hI = floor(h * 6f).toInt()
|
val hI = floor(h * 6f).toInt()
|
||||||
val f = h * 6f - hI
|
val f = h * 6f - hI
|
||||||
val p = v * (1f - s)
|
val p = v * (1f - s)
|
||||||
val q = v * (1f - f * s)
|
val q = v * (1f - f * s)
|
||||||
val t = v * (1f - (1f - f) * s)
|
val t = v * (1f - (1f - f) * s)
|
||||||
|
|
||||||
var r = 256f
|
var r = 256f
|
||||||
var g = 256f
|
var g = 256f
|
||||||
var b = 256f
|
var b = 256f
|
||||||
|
|
||||||
when (hI) {
|
when (hI) {
|
||||||
0 -> {
|
0 -> {
|
||||||
r = v; g = t; b = p
|
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())
|
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())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,32 +127,32 @@ private fun HSVtoRGB(hueValue: Int, saturation: Int, brightness: Int): Triple<In
|
|||||||
* For some reason if a matching hue is not found, just return Monochrome.
|
* For some reason if a matching hue is not found, just return Monochrome.
|
||||||
*/
|
*/
|
||||||
private fun matchColor(hueValue: Int, hue: Hue): Color {
|
private fun matchColor(hueValue: Int, hue: Hue): Color {
|
||||||
return when (hue) {
|
return when (hue) {
|
||||||
is ColorHue -> hue.color
|
is ColorHue -> hue.color
|
||||||
else -> {
|
else -> {
|
||||||
// Maps red colors to make picking hue easier
|
// Maps red colors to make picking hue easier
|
||||||
var hueVal = hueValue
|
var hueVal = hueValue
|
||||||
if (hueVal in 334..360) {
|
if (hueVal in 334..360) {
|
||||||
hueVal -= 360
|
hueVal -= 360
|
||||||
}
|
}
|
||||||
|
|
||||||
for (color in Color.values()) {
|
for (color in Color.values()) {
|
||||||
if (hueVal in color.hueRange.first..color.hueRange.second) {
|
if (hueVal in color.hueRange.first..color.hueRange.second) {
|
||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Returning Monochrome if we can't find a value, but this should never happen
|
// Returning Monochrome if we can't find a value, but this should never happen
|
||||||
return Color.monochrome
|
return Color.monochrome
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun randomWithin(range: Pair<Int, Int>): Int {
|
private fun randomWithin(range: Pair<Int, Int>): Int {
|
||||||
// Generate random evenly distinct number from:
|
// Generate random evenly distinct number from:
|
||||||
// https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
// https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
||||||
val goldenRatio = 0.618033988749895
|
val goldenRatio = 0.618033988749895
|
||||||
var r = Random.nextDouble()
|
var r = Random.nextDouble()
|
||||||
r += goldenRatio
|
r += goldenRatio
|
||||||
r %= 1
|
r %= 1
|
||||||
return floor(range.first + r * (range.second + 1 - range.first)).toInt()
|
return floor(range.first + r * (range.second + 1 - range.first)).toInt()
|
||||||
}
|
}
|
@ -1,7 +1,12 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets.indents
|
package com.github.izhangzhihao.rainbow.brackets.indents
|
||||||
|
|
||||||
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
import com.github.izhangzhihao.rainbow.brackets.RainbowInfo
|
||||||
import com.github.izhangzhihao.rainbow.brackets.util.*
|
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.Document
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.SoftWrap
|
import com.intellij.openapi.editor.SoftWrap
|
||||||
@ -23,236 +28,242 @@ import com.intellij.ui.paint.LinePainter2D
|
|||||||
import com.intellij.util.text.CharArrayUtil
|
import com.intellij.util.text.CharArrayUtil
|
||||||
import java.awt.Graphics
|
import java.awt.Graphics
|
||||||
import java.awt.Graphics2D
|
import java.awt.Graphics2D
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
/** From [com.intellij.codeInsight.daemon.impl.IndentGuideRenderer]
|
/** 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
|
* 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 {
|
class RainbowIndentGuideRenderer : CustomHighlighterRenderer {
|
||||||
override fun paint(editor: Editor, highlighter: RangeHighlighter, g: Graphics) {
|
override fun paint(editor: Editor, highlighter: RangeHighlighter, g: Graphics) {
|
||||||
if (editor !is EditorEx) return
|
if (editor !is EditorEx) return
|
||||||
|
|
||||||
val rainbowInfo = getRainbowInfo(editor, highlighter) ?: return
|
val rainbowInfo = getRainbowInfo(editor, highlighter) ?: return
|
||||||
|
|
||||||
val startOffset = highlighter.startOffset
|
val startOffset = highlighter.startOffset
|
||||||
val doc = highlighter.document
|
val doc = highlighter.document
|
||||||
if (startOffset >= doc.textLength) return
|
if (startOffset >= doc.textLength) return
|
||||||
|
|
||||||
val endOffset = highlighter.endOffset
|
val endOffset = highlighter.endOffset
|
||||||
|
|
||||||
var off: Int
|
var off: Int
|
||||||
var startLine = doc.getLineNumber(startOffset)
|
var startLine = doc.getLineNumber(startOffset)
|
||||||
|
|
||||||
val chars = doc.charsSequence
|
val chars = doc.charsSequence
|
||||||
do {
|
do {
|
||||||
val start = doc.getLineStartOffset(startLine)
|
val start = doc.getLineStartOffset(startLine)
|
||||||
val end = doc.getLineEndOffset(startLine)
|
val end = doc.getLineEndOffset(startLine)
|
||||||
off = CharArrayUtil.shiftForward(chars, start, end, " \t")
|
off = CharArrayUtil.shiftForward(chars, start, end, " \t")
|
||||||
startLine--
|
startLine--
|
||||||
} while (startLine > 1 && off < doc.textLength && chars[off] == '\n')
|
} while (startLine > 1 && off < doc.textLength && chars[off] == '\n')
|
||||||
|
|
||||||
val startPosition = editor.offsetToVisualPosition(off)
|
val startPosition = editor.offsetToVisualPosition(off)
|
||||||
val indentColumn = startPosition.column
|
val indentColumn = startPosition.column
|
||||||
|
|
||||||
if (indentColumn <= 0) return
|
if (indentColumn <= 0) return
|
||||||
|
|
||||||
val foldingModel = editor.foldingModel
|
val foldingModel = editor.foldingModel
|
||||||
if (foldingModel.isOffsetCollapsed(off)) return
|
if (foldingModel.isOffsetCollapsed(off)) return
|
||||||
|
|
||||||
val headerRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(off)))
|
val headerRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(off)))
|
||||||
val tailRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineStartOffset(doc.getLineNumber(endOffset)))
|
val tailRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineStartOffset(doc.getLineNumber(endOffset)))
|
||||||
|
|
||||||
if (tailRegion != null && tailRegion === headerRegion) return
|
if (tailRegion != null && tailRegion === headerRegion) return
|
||||||
|
|
||||||
val guide = editor.indentsModel.caretIndentGuide
|
val guide = editor.indentsModel.caretIndentGuide
|
||||||
val selected = if (guide != null) {
|
val selected = if (guide != null) {
|
||||||
val caretModel = editor.caretModel
|
val caretModel = editor.caretModel
|
||||||
val caretOffset = caretModel.offset
|
val caretOffset = caretModel.offset
|
||||||
caretOffset in off until endOffset && caretModel.logicalPosition.column == indentColumn
|
caretOffset in off until endOffset && caretModel.logicalPosition.column == indentColumn
|
||||||
} else false
|
}
|
||||||
|
else false
|
||||||
|
|
||||||
val lineHeight = editor.getLineHeight()
|
val lineHeight = editor.getLineHeight()
|
||||||
val start = editor.visualPositionToXY(startPosition)
|
val start = editor.visualPositionToXY(startPosition)
|
||||||
start.y += lineHeight
|
start.y += lineHeight
|
||||||
val endPosition = editor.offsetToVisualPosition(endOffset)
|
val endPosition = editor.offsetToVisualPosition(endOffset)
|
||||||
val end = editor.visualPositionToXY(endPosition)
|
val end = editor.visualPositionToXY(endPosition)
|
||||||
var maxY = end.y
|
var maxY = end.y
|
||||||
if (endPosition.line == editor.offsetToVisualPosition(doc.textLength).line) {
|
if (endPosition.line == editor.offsetToVisualPosition(doc.textLength).line) {
|
||||||
maxY += lineHeight
|
maxY += lineHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
val clip = g.clipBounds
|
val clip = g.clipBounds
|
||||||
if (clip != null) {
|
if (clip != null) {
|
||||||
if (clip.y >= maxY || clip.y + clip.height <= start.y) {
|
if (clip.y >= maxY || clip.y + clip.height <= start.y) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
maxY = StrictMath.min(maxY, clip.y + clip.height)
|
maxY = StrictMath.min(maxY, clip.y + clip.height)
|
||||||
}
|
}
|
||||||
if (start.y >= maxY) return
|
if (start.y >= maxY) return
|
||||||
val targetX = Math.max(0, start.x + EditorPainter.getIndentGuideShift(editor)).toDouble()
|
val targetX = max(0, start.x + EditorPainter.getIndentGuideShift(editor)).toDouble()
|
||||||
g.color = if (selected) {
|
g.color = if (selected) {
|
||||||
rainbowInfo.color
|
rainbowInfo.color
|
||||||
} else {
|
}
|
||||||
val defaultBackground = editor.colorsScheme.defaultBackground
|
else {
|
||||||
rainbowInfo.color.alphaBlend(defaultBackground, 0.2f)
|
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:
|
// There is a possible case that indent line intersects soft wrap-introduced text. Example:
|
||||||
// this is a long line <soft-wrap>
|
// this is a long line <soft-wrap>
|
||||||
// that| is soft-wrapped
|
// that| is soft-wrapped
|
||||||
// |
|
// |
|
||||||
// | <- vertical indent
|
// | <- vertical indent
|
||||||
//
|
//
|
||||||
// Also it's possible that no additional intersections are added because of soft wrap:
|
// Also it's possible that no additional intersections are added because of soft wrap:
|
||||||
// this is a long line <soft-wrap>
|
// this is a long line <soft-wrap>
|
||||||
// | that is soft-wrapped
|
// | that is soft-wrapped
|
||||||
// |
|
// |
|
||||||
// | <- vertical indent
|
// | <- vertical indent
|
||||||
// We want to use the following approach then:
|
// We want to use the following approach then:
|
||||||
// 1. Show only active indent if it crosses soft wrap-introduced text;
|
// 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;
|
// 2. Show indent as is if it doesn't intersect with soft wrap-introduced text;
|
||||||
val softWraps = editor.softWrapModel.registeredSoftWraps
|
val softWraps = editor.softWrapModel.registeredSoftWraps
|
||||||
if (selected || softWraps.isEmpty()) {
|
if (selected || softWraps.isEmpty()) {
|
||||||
LinePainter2D.paint(g as Graphics2D, targetX, start.y.toDouble(), targetX, maxY - 1.toDouble())
|
LinePainter2D.paint(g as Graphics2D, targetX, start.y.toDouble(), targetX, maxY - 1.toDouble())
|
||||||
} else {
|
}
|
||||||
var startY = start.y
|
else {
|
||||||
var startVisualLine = startPosition.line + 1
|
var startY = start.y
|
||||||
if (clip != null && startY < clip.y) {
|
var startVisualLine = startPosition.line + 1
|
||||||
startY = clip.y
|
if (clip != null && startY < clip.y) {
|
||||||
startVisualLine = editor.yToVisualLine(clip.y)
|
startY = clip.y
|
||||||
}
|
startVisualLine = editor.yToVisualLine(clip.y)
|
||||||
val it = VisualLinesIterator(editor as EditorImpl, startVisualLine)
|
}
|
||||||
while (!it.atEnd()) {
|
val it = VisualLinesIterator(editor as EditorImpl, startVisualLine)
|
||||||
val currY: Int = it.y
|
while (!it.atEnd()) {
|
||||||
if (currY >= startY) {
|
val currY: Int = it.y
|
||||||
if (currY >= maxY) break
|
if (currY >= startY) {
|
||||||
if (it.startsWithSoftWrap()) {
|
if (currY >= maxY) break
|
||||||
val softWrap: SoftWrap = softWraps[it.startOrPrevWrapIndex]
|
if (it.startsWithSoftWrap()) {
|
||||||
if (softWrap.indentInColumns < indentColumn) {
|
val softWrap: SoftWrap = softWraps[it.startOrPrevWrapIndex]
|
||||||
if (startY < currY) {
|
if (softWrap.indentInColumns < indentColumn) {
|
||||||
LinePainter2D.paint((g as Graphics2D), targetX, startY.toDouble(), targetX, currY - 1.toDouble())
|
if (startY < currY) {
|
||||||
}
|
LinePainter2D.paint((g as Graphics2D), targetX, startY.toDouble(), targetX, currY - 1.toDouble())
|
||||||
startY = currY + lineHeight
|
}
|
||||||
}
|
startY = currY + lineHeight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it.advance()
|
}
|
||||||
}
|
it.advance()
|
||||||
if (startY < maxY) {
|
}
|
||||||
LinePainter2D.paint((g as Graphics2D), targetX, startY.toDouble(), targetX, maxY - 1.toDouble())
|
if (startY < maxY) {
|
||||||
}
|
LinePainter2D.paint((g as Graphics2D), targetX, startY.toDouble(), targetX, maxY - 1.toDouble())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val XML_TAG_PARENT_CONDITION = Condition<PsiElement> { it is XmlTag }
|
private val XML_TAG_PARENT_CONDITION = Condition<PsiElement> { it is XmlTag }
|
||||||
private val XML_END_TAG_START_CONDITION: (PsiElement) -> Boolean = { element ->
|
private val XML_END_TAG_START_CONDITION: (PsiElement) -> Boolean = { element ->
|
||||||
element is XmlToken && element.tokenType == XmlTokenType.XML_END_TAG_START
|
element is XmlToken && element.tokenType == XmlTokenType.XML_END_TAG_START
|
||||||
}
|
}
|
||||||
private val XML_TAG_END_CONDITION: (PsiElement) -> Boolean = { element ->
|
private val XML_TAG_END_CONDITION: (PsiElement) -> Boolean = { element ->
|
||||||
element is XmlToken && element.tokenType == XmlTokenType.XML_TAG_END
|
element is XmlToken && element.tokenType == XmlTokenType.XML_TAG_END
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRainbowInfo(editor: EditorEx, highlighter: RangeHighlighter): RainbowInfo? {
|
private fun getRainbowInfo(editor: EditorEx, highlighter: RangeHighlighter): RainbowInfo? {
|
||||||
val virtualFile = editor.virtualFile?.takeIf { it.isValid } ?: return null
|
val virtualFile = editor.virtualFile?.takeIf { it.isValid } ?: return null
|
||||||
val document = editor.document
|
val document = editor.document
|
||||||
val project = editor.project ?: return null
|
val project = editor.project ?: return null
|
||||||
val psiFile = PsiManager.getInstance(project).findFile(virtualFile) ?: return null
|
val psiFile = PsiManager.getInstance(project).findFile(virtualFile) ?: return null
|
||||||
var element = try {
|
var element = try {
|
||||||
psiFile.findElementAt(highlighter.endOffset)?.parent ?: return null
|
psiFile.findElementAt(highlighter.endOffset)?.parent ?: return null
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
var rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element]
|
var rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element]
|
||||||
if (rainbowInfo == null && psiFile is XmlFile && element !is XmlTag) {
|
if (rainbowInfo == null && psiFile is XmlFile && element !is XmlTag) {
|
||||||
element = PsiTreeUtil.findFirstParent(element, true, XML_TAG_PARENT_CONDITION) ?: return null
|
element = PsiTreeUtil.findFirstParent(element, true, XML_TAG_PARENT_CONDITION) ?: return null
|
||||||
rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element] ?: return null
|
rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[element] ?: return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!element.isValid || !checkBoundary(document, element, highlighter)) {
|
if (!element.isValid || !checkBoundary(document, element, highlighter)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return rainbowInfo
|
return rainbowInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* introduced from https://github.com/izhangzhihao/intellij-rainbow-brackets/commit/d9d40e6910e9c15fbdcba12280df18019ea170b5
|
* introduced from https://github.com/izhangzhihao/intellij-rainbow-brackets/commit/d9d40e6910e9c15fbdcba12280df18019ea170b5
|
||||||
*/
|
*/
|
||||||
private fun checkBoundary(document: Document, element: PsiElement, highlighter: RangeHighlighter): Boolean {
|
private fun checkBoundary(document: Document, element: PsiElement, highlighter: RangeHighlighter): Boolean {
|
||||||
val elementStartLine = document.lineNumber(element.startOffset) ?: return false
|
val elementStartLine = document.lineNumber(element.startOffset) ?: return false
|
||||||
val highlighterStartLine = document.lineNumber(highlighter.startOffset) ?: return false
|
val highlighterStartLine = document.lineNumber(highlighter.startOffset) ?: return false
|
||||||
|
|
||||||
var xmlStartTagEndLine: Int? = null
|
var xmlStartTagEndLine: Int? = null
|
||||||
var xmlEndTagStartLine: Int? = null
|
var xmlEndTagStartLine: Int? = null
|
||||||
|
|
||||||
val isValidStartBoundary = if (element is XmlTag) {
|
val isValidStartBoundary = if (element is XmlTag) {
|
||||||
/*
|
/*
|
||||||
* <tag // [*] element & highlighter start line
|
* <tag // [*] element & highlighter start line
|
||||||
* | <- vertical indent
|
* | <- vertical indent
|
||||||
* > // [*] highlighter start/end line, start tag end line
|
* > // [*] highlighter start/end line, start tag end line
|
||||||
* | <- vertical indent
|
* | <- vertical indent
|
||||||
* </tag // [*] highlighter start/end line, end tag start line
|
* </tag // [*] highlighter start/end line, end tag start line
|
||||||
* | <- vertical indent
|
* | <- vertical indent
|
||||||
* > // [ ] element/highlighter end line
|
* > // [ ] element/highlighter end line
|
||||||
*/
|
*/
|
||||||
xmlStartTagEndLine = element.getStartTagEndLineNumber(document)
|
xmlStartTagEndLine = element.getStartTagEndLineNumber(document)
|
||||||
xmlEndTagStartLine = element.getEndTagStartLineNumber(document)
|
xmlEndTagStartLine = element.getEndTagStartLineNumber(document)
|
||||||
|
|
||||||
highlighterStartLine == elementStartLine ||
|
highlighterStartLine == elementStartLine ||
|
||||||
highlighterStartLine == xmlStartTagEndLine ||
|
highlighterStartLine == xmlStartTagEndLine ||
|
||||||
highlighterStartLine == xmlEndTagStartLine
|
highlighterStartLine == xmlEndTagStartLine
|
||||||
} else {
|
}
|
||||||
/*
|
else {
|
||||||
* Element start line > Highlighter start line:
|
/*
|
||||||
* function foo(arg1, // highlighter start line
|
* Element start line > Highlighter start line:
|
||||||
* | arg2) { // element start line
|
* function foo(arg1, // highlighter start line
|
||||||
* | <- vertical indent
|
* | arg2) { // element start line
|
||||||
* } // element & highlighter end line
|
* | <- vertical indent
|
||||||
*/
|
* } // element & highlighter end line
|
||||||
elementStartLine >= highlighterStartLine
|
*/
|
||||||
}
|
elementStartLine >= highlighterStartLine
|
||||||
if (!isValidStartBoundary) {
|
}
|
||||||
return false
|
if (!isValidStartBoundary) {
|
||||||
}
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
val elementEndLine = document.lineNumber(element.endOffset) ?: return false
|
val elementEndLine = document.lineNumber(element.endOffset) ?: return false
|
||||||
val highlighterEndLine = document.lineNumber(highlighter.endOffset) ?: return false
|
val highlighterEndLine = document.lineNumber(highlighter.endOffset) ?: return false
|
||||||
val isValidEndBoundary = if (element is XmlTag) {
|
val isValidEndBoundary = if (element is XmlTag) {
|
||||||
/*
|
/*
|
||||||
* <tag // [ ] element & highlighter start line
|
* <tag // [ ] element & highlighter start line
|
||||||
* | <- vertical indent
|
* | <- vertical indent
|
||||||
* > // [*] highlighter start/end line, start tag end line
|
* > // [*] highlighter start/end line, start tag end line
|
||||||
* | <- vertical indent
|
* | <- vertical indent
|
||||||
* </tag // [*] highlighter start/end line, end tag start line
|
* </tag // [*] highlighter start/end line, end tag start line
|
||||||
* | <- vertical indent
|
* | <- vertical indent
|
||||||
* > // [*] element/highlighter end line
|
* > // [*] element/highlighter end line
|
||||||
*/
|
*/
|
||||||
highlighterEndLine == elementEndLine ||
|
highlighterEndLine == elementEndLine ||
|
||||||
highlighterEndLine == xmlStartTagEndLine ||
|
highlighterEndLine == xmlStartTagEndLine ||
|
||||||
highlighterEndLine == xmlEndTagStartLine
|
highlighterEndLine == xmlEndTagStartLine
|
||||||
} else {
|
}
|
||||||
/*
|
else {
|
||||||
* Element end line != Highlighter end line:
|
/*
|
||||||
* function foo() { // element & highlighter start line
|
* Element end line != Highlighter end line:
|
||||||
* | <- vertical indent
|
* function foo() { // element & highlighter start line
|
||||||
* var bar = "bar"; // highlighter end line
|
* | <- vertical indent
|
||||||
* } // element end line
|
* var bar = "bar"; // highlighter end line
|
||||||
*/
|
* } // element end line
|
||||||
elementEndLine == highlighterEndLine
|
*/
|
||||||
}
|
elementEndLine == highlighterEndLine
|
||||||
if (!isValidEndBoundary) {
|
}
|
||||||
return false
|
if (!isValidEndBoundary) {
|
||||||
}
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun XmlTag.getStartTagEndLineNumber(document: Document): Int? =
|
private fun XmlTag.getStartTagEndLineNumber(document: Document): Int? =
|
||||||
firstChild?.findNextSibling(XML_TAG_END_CONDITION)?.let { document.lineNumber(it.startOffset) }
|
firstChild?.findNextSibling(XML_TAG_END_CONDITION)?.let { document.lineNumber(it.startOffset) }
|
||||||
|
|
||||||
private fun XmlTag.getEndTagStartLineNumber(document: Document): Int? =
|
private fun XmlTag.getEndTagStartLineNumber(document: Document): Int? =
|
||||||
lastChild?.findPrevSibling(XML_END_TAG_START_CONDITION)?.let { document.lineNumber(it.startOffset) }
|
lastChild?.findPrevSibling(XML_END_TAG_START_CONDITION)?.let { document.lineNumber(it.startOffset) }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,338 +28,343 @@ import com.intellij.util.containers.IntStack
|
|||||||
import com.intellij.util.text.CharArrayUtil
|
import com.intellij.util.text.CharArrayUtil
|
||||||
import java.lang.StrictMath.abs
|
import java.lang.StrictMath.abs
|
||||||
import java.lang.StrictMath.min
|
import java.lang.StrictMath.min
|
||||||
import java.util.*
|
import java.util.Collections
|
||||||
|
|
||||||
/** From [com.intellij.codeInsight.daemon.impl.IndentsPass]
|
/** 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
|
* 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#`
|
* mirror changes start from `Make it possible to ignore indent guides more granularly and do so for C#`
|
||||||
* */
|
* */
|
||||||
class RainbowIndentsPass internal constructor(
|
class RainbowIndentsPass internal constructor(
|
||||||
project: Project,
|
project: Project,
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
private val myFile: PsiFile
|
private val myFile: PsiFile,
|
||||||
) : TextEditorHighlightingPass(project, editor.document, false), DumbAware {
|
) : TextEditorHighlightingPass(project, editor.document, false), DumbAware {
|
||||||
|
|
||||||
private val myEditor: EditorEx = editor as EditorEx
|
private val myEditor: EditorEx = editor as EditorEx
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var myRanges = emptyList<TextRange>()
|
private var myRanges = emptyList<TextRange>()
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var myDescriptors = emptyList<IndentGuideDescriptor>()
|
private var myDescriptors = emptyList<IndentGuideDescriptor>()
|
||||||
|
|
||||||
override fun doCollectInformation(progress: ProgressIndicator) {
|
override fun doCollectInformation(progress: ProgressIndicator) {
|
||||||
val stamp = myEditor.getUserData(LAST_TIME_INDENTS_BUILT)
|
val stamp = myEditor.getUserData(LAST_TIME_INDENTS_BUILT)
|
||||||
if (stamp != null && stamp.toLong() == nowStamp()) return
|
if (stamp != null && stamp.toLong() == nowStamp()) return
|
||||||
|
|
||||||
myDescriptors = buildDescriptors()
|
myDescriptors = buildDescriptors()
|
||||||
|
|
||||||
val ranges = ArrayList<TextRange>()
|
val ranges = ArrayList<TextRange>()
|
||||||
for (descriptor in myDescriptors) {
|
for (descriptor in myDescriptors) {
|
||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
val endOffset = if (descriptor.endLine < document.lineCount) {
|
val endOffset = if (descriptor.endLine < document.lineCount) {
|
||||||
document.getLineStartOffset(descriptor.endLine)
|
document.getLineStartOffset(descriptor.endLine)
|
||||||
} else {
|
}
|
||||||
document.textLength
|
else {
|
||||||
}
|
document.textLength
|
||||||
ranges.add(TextRange(document.getLineStartOffset(descriptor.startLine), endOffset))
|
}
|
||||||
}
|
ranges.add(TextRange(document.getLineStartOffset(descriptor.startLine), endOffset))
|
||||||
|
}
|
||||||
|
|
||||||
Collections.sort(ranges, Segment.BY_START_OFFSET_THEN_END_OFFSET)
|
Collections.sort(ranges, Segment.BY_START_OFFSET_THEN_END_OFFSET)
|
||||||
myRanges = ranges
|
myRanges = ranges
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun nowStamp(): Long = if (isRainbowIndentGuidesShown(this.myProject)) document.modificationStamp xor (EditorUtil.getTabSize(myEditor).toLong() shl 24) else -1
|
private fun nowStamp(): Long = if (isRainbowIndentGuidesShown(this.myProject)) document.modificationStamp xor (EditorUtil.getTabSize(myEditor).toLong() shl 24) else -1
|
||||||
|
|
||||||
override fun doApplyInformationToEditor() {
|
override fun doApplyInformationToEditor() {
|
||||||
val stamp = myEditor.getUserData(LAST_TIME_INDENTS_BUILT)
|
val stamp = myEditor.getUserData(LAST_TIME_INDENTS_BUILT)
|
||||||
val nowStamp = nowStamp()
|
val nowStamp = nowStamp()
|
||||||
|
|
||||||
if (stamp == nowStamp) return
|
if (stamp == nowStamp) return
|
||||||
|
|
||||||
myEditor.putUserData(LAST_TIME_INDENTS_BUILT, nowStamp)
|
myEditor.putUserData(LAST_TIME_INDENTS_BUILT, nowStamp)
|
||||||
|
|
||||||
val oldHighlighters = myEditor.getUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY)
|
val oldHighlighters = myEditor.getUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY)
|
||||||
if (nowStamp == -1L) {
|
if (nowStamp == -1L) {
|
||||||
if (oldHighlighters != null) {
|
if (oldHighlighters != null) {
|
||||||
for (oldHighlighter in oldHighlighters) {
|
for (oldHighlighter in oldHighlighters) {
|
||||||
oldHighlighter.dispose()
|
oldHighlighter.dispose()
|
||||||
}
|
}
|
||||||
oldHighlighters.clear()
|
oldHighlighters.clear()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val newHighlighters = ArrayList<RangeHighlighter>()
|
val newHighlighters = ArrayList<RangeHighlighter>()
|
||||||
val mm = myEditor.markupModel
|
val mm = myEditor.markupModel
|
||||||
var curRange = 0
|
var curRange = 0
|
||||||
|
|
||||||
if (oldHighlighters != null) {
|
if (oldHighlighters != null) {
|
||||||
// after document change some range highlighters could have become invalid, or the order could have been broken
|
// 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 }
|
oldHighlighters.sortWith(Comparator.comparing { h: RangeHighlighter -> !h.isValid }
|
||||||
.thenComparing(Segment.BY_START_OFFSET_THEN_END_OFFSET))
|
.thenComparing(Segment.BY_START_OFFSET_THEN_END_OFFSET))
|
||||||
|
|
||||||
var curHighlight = 0
|
var curHighlight = 0
|
||||||
while (curRange < myRanges.size && curHighlight < oldHighlighters.size) {
|
while (curRange < myRanges.size && curHighlight < oldHighlighters.size) {
|
||||||
val range = myRanges[curRange]
|
val range = myRanges[curRange]
|
||||||
val highlighter = oldHighlighters[curHighlight]
|
val highlighter = oldHighlighters[curHighlight]
|
||||||
if (!highlighter.isValid) break
|
if (!highlighter.isValid) break
|
||||||
|
|
||||||
val cmp = compare(range, highlighter)
|
val cmp = compare(range, highlighter)
|
||||||
when {
|
when {
|
||||||
cmp < 0 -> {
|
cmp < 0 -> {
|
||||||
newHighlighters.add(createHighlighter(mm, range))
|
newHighlighters.add(createHighlighter(mm, range))
|
||||||
curRange++
|
curRange++
|
||||||
}
|
}
|
||||||
cmp > 0 -> {
|
|
||||||
highlighter.dispose()
|
|
||||||
curHighlight++
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
newHighlighters.add(highlighter)
|
|
||||||
curHighlight++
|
|
||||||
curRange++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (curHighlight < oldHighlighters.size) {
|
cmp > 0 -> {
|
||||||
val highlighter = oldHighlighters[curHighlight]
|
highlighter.dispose()
|
||||||
if (!highlighter.isValid) break
|
curHighlight++
|
||||||
highlighter.dispose()
|
}
|
||||||
curHighlight++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val startRangeIndex = curRange
|
else -> {
|
||||||
DocumentUtil.executeInBulk(document, myRanges.size > 10000) {
|
newHighlighters.add(highlighter)
|
||||||
for (i in startRangeIndex until myRanges.size) {
|
curHighlight++
|
||||||
newHighlighters.add(createHighlighter(mm, myRanges[i]))
|
curRange++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
myEditor.putUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY, newHighlighters)
|
while (curHighlight < oldHighlighters.size) {
|
||||||
myEditor.indentsModel.assumeIndents(myDescriptors)
|
val highlighter = oldHighlighters[curHighlight]
|
||||||
}
|
if (!highlighter.isValid) break
|
||||||
|
highlighter.dispose()
|
||||||
|
curHighlight++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildDescriptors(): List<IndentGuideDescriptor> {
|
val startRangeIndex = curRange
|
||||||
if (!isRainbowIndentGuidesShown(this.myProject)) return emptyList()
|
DocumentUtil.executeInBulk(document, myRanges.size > 10000) {
|
||||||
|
for (i in startRangeIndex until myRanges.size) {
|
||||||
|
newHighlighters.add(createHighlighter(mm, myRanges[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val calculator = IndentsCalculator()
|
myEditor.putUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY, newHighlighters)
|
||||||
calculator.calculate()
|
myEditor.indentsModel.assumeIndents(myDescriptors)
|
||||||
val lineIndents = calculator.lineIndents
|
}
|
||||||
|
|
||||||
val lines = IntStack()
|
private fun buildDescriptors(): List<IndentGuideDescriptor> {
|
||||||
val indents = IntStack()
|
if (!isRainbowIndentGuidesShown(this.myProject)) return emptyList()
|
||||||
|
|
||||||
lines.push(0)
|
val calculator = IndentsCalculator()
|
||||||
indents.push(0)
|
calculator.calculate()
|
||||||
val descriptors = ArrayList<IndentGuideDescriptor>()
|
val lineIndents = calculator.lineIndents
|
||||||
for (line in 1 until lineIndents.size) {
|
|
||||||
ProgressManager.checkCanceled()
|
|
||||||
val curIndent = abs(lineIndents[line])
|
|
||||||
|
|
||||||
while (!indents.empty() && curIndent <= indents.peek()) {
|
val lines = IntStack()
|
||||||
ProgressManager.checkCanceled()
|
val indents = IntStack()
|
||||||
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
|
lines.push(0)
|
||||||
val prevIndent = abs(lineIndents[prevLine])
|
indents.push(0)
|
||||||
|
val descriptors = ArrayList<IndentGuideDescriptor>()
|
||||||
|
for (line in 1 until lineIndents.size) {
|
||||||
|
ProgressManager.checkCanceled()
|
||||||
|
val curIndent = abs(lineIndents[line])
|
||||||
|
|
||||||
if (curIndent - prevIndent > 1) {
|
while (!indents.empty() && curIndent <= indents.peek()) {
|
||||||
lines.push(prevLine)
|
ProgressManager.checkCanceled()
|
||||||
indents.push(prevIndent)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (!indents.empty()) {
|
val prevLine = line - 1
|
||||||
ProgressManager.checkCanceled()
|
val prevIndent = abs(lineIndents[prevLine])
|
||||||
val level = indents.pop()
|
|
||||||
val startLine = lines.pop()
|
|
||||||
if (level > 0) {
|
|
||||||
descriptors.add(createDescriptor(level, startLine, document.lineCount, lineIndents))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return descriptors
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createDescriptor(
|
if (curIndent - prevIndent > 1) {
|
||||||
level: Int,
|
lines.push(prevLine)
|
||||||
startLine: Int,
|
indents.push(prevIndent)
|
||||||
endLine: Int,
|
}
|
||||||
lineIndents: IntArray
|
}
|
||||||
): IndentGuideDescriptor {
|
|
||||||
var sLine = startLine
|
|
||||||
while (sLine > 0 && lineIndents[sLine] < 0) sLine--
|
|
||||||
// int codeConstructStartLine = findCodeConstructStartLine(startLine);
|
|
||||||
return IndentGuideDescriptor(level, sLine, endLine)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
while (!indents.empty()) {
|
||||||
private fun findCodeConstructStart(startLine: Int): Int? {
|
ProgressManager.checkCanceled()
|
||||||
val document = myEditor.document
|
val level = indents.pop()
|
||||||
val text = document.immutableCharSequence
|
val startLine = lines.pop()
|
||||||
val lineStartOffset = document.getLineStartOffset(startLine)
|
if (level > 0) {
|
||||||
val firstNonWsOffset = CharArrayUtil.shiftForward(text, lineStartOffset, " \t")
|
descriptors.add(createDescriptor(level, startLine, document.lineCount, lineIndents))
|
||||||
val type = PsiUtilBase.getPsiFileAtOffset(myFile, firstNonWsOffset).fileType
|
}
|
||||||
val language = PsiUtilCore.getLanguageAtOffset(myFile, firstNonWsOffset)
|
}
|
||||||
val braceMatcher = BraceMatchingUtil.getBraceMatcher(type, language)
|
return descriptors
|
||||||
val iterator = myEditor.highlighter.createIterator(firstNonWsOffset)
|
}
|
||||||
return if (braceMatcher.isLBraceToken(iterator, text, type)) {
|
|
||||||
braceMatcher.getCodeConstructStart(myFile, firstNonWsOffset)
|
private fun createDescriptor(
|
||||||
} else null
|
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 {
|
private fun findCodeConstructStartLine(startLine: Int): Int {
|
||||||
val codeConstructStart = findCodeConstructStart(startLine)
|
val codeConstructStart = findCodeConstructStart(startLine)
|
||||||
return if (codeConstructStart != null) myEditor.document.getLineNumber(codeConstructStart) else startLine
|
return if (codeConstructStart != null) myEditor.document.getLineNumber(codeConstructStart) else startLine
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private inner class IndentsCalculator() {
|
private inner class IndentsCalculator {
|
||||||
val myComments: MutableMap<Language, TokenSet> = HashMap()
|
val myComments: MutableMap<Language, TokenSet> = HashMap()
|
||||||
val lineIndents: IntArray // negative value means the line is empty (or contains a comment) and indent
|
val lineIndents = IntArray(document.lineCount) // negative value means the line is empty (or contains a comment) and indent
|
||||||
|
|
||||||
// (denoted by absolute value) was deduced from enclosing non-empty lines
|
// (denoted by absolute value) was deduced from enclosing non-empty lines
|
||||||
val myChars: CharSequence
|
val myChars: CharSequence
|
||||||
|
|
||||||
init {
|
init {
|
||||||
lineIndents = IntArray(document.lineCount)
|
myChars = document.charsSequence
|
||||||
myChars = document.charsSequence
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates line indents for the [target document][.myDocument].
|
* Calculates line indents for the [target document][.myDocument].
|
||||||
*/
|
*/
|
||||||
fun calculate() {
|
fun calculate() {
|
||||||
val fileType = myFile.fileType
|
val fileType = myFile.fileType
|
||||||
val tabSize = EditorUtil.getTabSize(myEditor)
|
val tabSize = EditorUtil.getTabSize(myEditor)
|
||||||
|
|
||||||
for (line in lineIndents.indices) {
|
for (line in lineIndents.indices) {
|
||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
val lineStart = document.getLineStartOffset(line)
|
val lineStart = document.getLineStartOffset(line)
|
||||||
val lineEnd = document.getLineEndOffset(line)
|
val lineEnd = document.getLineEndOffset(line)
|
||||||
var offset = lineStart
|
var offset = lineStart
|
||||||
var column = 0
|
var column = 0
|
||||||
outer@ while (offset < lineEnd) {
|
outer@ while (offset < lineEnd) {
|
||||||
when (myChars[offset]) {
|
when (myChars[offset]) {
|
||||||
' ' -> column++
|
' ' -> column++
|
||||||
'\t' -> column = (column / tabSize + 1) * tabSize
|
'\t' -> column = (column / tabSize + 1) * tabSize
|
||||||
else -> break@outer
|
else -> break@outer
|
||||||
}
|
}
|
||||||
offset++
|
offset++
|
||||||
}
|
}
|
||||||
// treating commented lines in the same way as empty lines
|
// treating commented lines in the same way as empty lines
|
||||||
// Blank line marker
|
// Blank line marker
|
||||||
lineIndents[line] = if (offset == lineEnd || isComment(offset)) -1 else column
|
lineIndents[line] = if (offset == lineEnd || isComment(offset)) -1 else column
|
||||||
}
|
}
|
||||||
|
|
||||||
var topIndent = 0
|
var topIndent = 0
|
||||||
var line = 0
|
var line = 0
|
||||||
while (line < lineIndents.size) {
|
while (line < lineIndents.size) {
|
||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
if (lineIndents[line] >= 0) {
|
if (lineIndents[line] >= 0) {
|
||||||
topIndent = lineIndents[line]
|
topIndent = lineIndents[line]
|
||||||
} else {
|
}
|
||||||
val startLine = line
|
else {
|
||||||
while (line < lineIndents.size && lineIndents[line] < 0) {
|
val startLine = line
|
||||||
line++
|
while (line < lineIndents.size && lineIndents[line] < 0) {
|
||||||
}
|
line++
|
||||||
|
}
|
||||||
|
|
||||||
val bottomIndent = if (line < lineIndents.size) lineIndents[line] else topIndent
|
val bottomIndent = if (line < lineIndents.size) lineIndents[line] else topIndent
|
||||||
|
|
||||||
var indent = min(topIndent, bottomIndent)
|
var indent = min(topIndent, bottomIndent)
|
||||||
if (bottomIndent < topIndent) {
|
if (bottomIndent < topIndent) {
|
||||||
val lineStart = document.getLineStartOffset(line)
|
val lineStart = document.getLineStartOffset(line)
|
||||||
val lineEnd = document.getLineEndOffset(line)
|
val lineEnd = document.getLineEndOffset(line)
|
||||||
val nonWhitespaceOffset = CharArrayUtil.shiftForward(myChars, lineStart, lineEnd, " \t")
|
val nonWhitespaceOffset = CharArrayUtil.shiftForward(myChars, lineStart, lineEnd, " \t")
|
||||||
val iterator = myEditor.highlighter.createIterator(nonWhitespaceOffset)
|
val iterator = myEditor.highlighter.createIterator(nonWhitespaceOffset)
|
||||||
val tokenType = iterator.tokenType
|
val tokenType = iterator.tokenType
|
||||||
if (BraceMatchingUtil.isRBraceToken(iterator, myChars, fileType) ||
|
if (BraceMatchingUtil.isRBraceToken(iterator, myChars, fileType) ||
|
||||||
tokenType != null &&
|
tokenType != null &&
|
||||||
CodeBlockSupportHandler.findMarkersRanges(myFile, tokenType.language, nonWhitespaceOffset).isNotEmpty()) {
|
CodeBlockSupportHandler.findMarkersRanges(myFile, tokenType.language, nonWhitespaceOffset).isNotEmpty()
|
||||||
indent = topIndent
|
) {
|
||||||
}
|
indent = topIndent
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (blankLine in startLine until line) {
|
for (blankLine in startLine until line) {
|
||||||
assert(lineIndents[blankLine] == -1)
|
assert(lineIndents[blankLine] == -1)
|
||||||
lineIndents[blankLine] = -min(topIndent, indent)
|
lineIndents[blankLine] = -min(topIndent, indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
line-- // will be incremented back at the end of the loop;
|
line-- // will be incremented back at the end of the loop;
|
||||||
}
|
}
|
||||||
line++
|
line++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isComment(offset: Int): Boolean {
|
private fun isComment(offset: Int): Boolean {
|
||||||
val it = myEditor.highlighter.createIterator(offset)
|
val it = myEditor.highlighter.createIterator(offset)
|
||||||
val tokenType = try {
|
val tokenType = try {
|
||||||
it.tokenType
|
it.tokenType
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val language = tokenType.language
|
val language = tokenType.language
|
||||||
var comments: TokenSet? = myComments[language]
|
var comments: TokenSet? = myComments[language]
|
||||||
if (comments == null) {
|
if (comments == null) {
|
||||||
val definition = LanguageParserDefinitions.INSTANCE.forLanguage(language)
|
val definition = LanguageParserDefinitions.INSTANCE.forLanguage(language)
|
||||||
if (definition != null) {
|
if (definition != null) {
|
||||||
comments = definition.commentTokens
|
comments = definition.commentTokens
|
||||||
}
|
}
|
||||||
if (comments == null) {
|
if (comments == null) {
|
||||||
return false
|
return false
|
||||||
} else {
|
}
|
||||||
myComments[language] = comments
|
else {
|
||||||
}
|
myComments[language] = comments
|
||||||
}
|
}
|
||||||
return comments.contains(tokenType)
|
}
|
||||||
}
|
return comments.contains(tokenType)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val INDENT_HIGHLIGHTERS_IN_EDITOR_KEY = Key.create<MutableList<RangeHighlighter>>("_INDENT_HIGHLIGHTERS_IN_EDITOR_KEY_")
|
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 LAST_TIME_INDENTS_BUILT = Key.create<Long>("_LAST_TIME_INDENTS_BUILT_")
|
||||||
|
|
||||||
private val RENDERER = RainbowIndentGuideRenderer()
|
private val RENDERER = RainbowIndentGuideRenderer()
|
||||||
|
|
||||||
private fun isRainbowIndentGuidesShown(project: Project): Boolean {
|
private fun isRainbowIndentGuidesShown(project: Project): Boolean {
|
||||||
if (RainbowSettings.instance.disableRainbowIndentsInZenMode && isZenModeEnabled(project)) {
|
if (RainbowSettings.instance.disableRainbowIndentsInZenMode && isZenModeEnabled(project)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return RainbowSettings.instance.isRainbowEnabled && RainbowSettings.instance.isShowRainbowIndentGuides
|
return RainbowSettings.instance.isRainbowEnabled && RainbowSettings.instance.isShowRainbowIndentGuides
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isZenModeEnabled(project: Project) =
|
private fun isZenModeEnabled(project: Project) =
|
||||||
ToggleZenModeAction.isZenModeEnabled(project)
|
ToggleZenModeAction.isZenModeEnabled(project)
|
||||||
|
|
||||||
private fun createHighlighter(mm: MarkupModel, range: TextRange): RangeHighlighter {
|
private fun createHighlighter(mm: MarkupModel, range: TextRange): RangeHighlighter {
|
||||||
return mm.addRangeHighlighter(
|
return mm.addRangeHighlighter(
|
||||||
range.startOffset,
|
range.startOffset,
|
||||||
range.endOffset,
|
range.endOffset,
|
||||||
0,
|
0,
|
||||||
null,
|
null,
|
||||||
HighlighterTargetArea.EXACT_RANGE
|
HighlighterTargetArea.EXACT_RANGE
|
||||||
).apply {
|
).apply {
|
||||||
customRenderer = RENDERER
|
customRenderer = RENDERER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compare(r: TextRange, h: RangeHighlighter): Int {
|
private fun compare(r: TextRange, h: RangeHighlighter): Int {
|
||||||
val answer = r.startOffset - h.startOffset
|
val answer = r.startOffset - h.startOffset
|
||||||
return if (answer != 0) answer else r.endOffset - h.endOffset
|
return if (answer != 0) answer else r.endOffset - h.endOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets.indents
|
package com.github.izhangzhihao.rainbow.brackets.indents
|
||||||
|
|
||||||
import com.intellij.codeHighlighting.*
|
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.editor.Editor
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
|
||||||
class RainbowIndentsPassFactory :
|
class RainbowIndentsPassFactory :
|
||||||
TextEditorHighlightingPassFactoryRegistrar, TextEditorHighlightingPassFactory {
|
TextEditorHighlightingPassFactoryRegistrar, TextEditorHighlightingPassFactory {
|
||||||
|
|
||||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass {
|
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass {
|
||||||
return RainbowIndentsPass(file.project, editor, file)
|
return RainbowIndentsPass(file.project, editor, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
override fun registerHighlightingPassFactory(registrar: TextEditorHighlightingPassRegistrar, project: Project) {
|
||||||
registrar.registerTextEditorHighlightingPass(
|
registrar.registerTextEditorHighlightingPass(
|
||||||
this,
|
this,
|
||||||
TextEditorHighlightingPassRegistrar.Anchor.LAST,
|
TextEditorHighlightingPassRegistrar.Anchor.LAST,
|
||||||
Pass.LAST_PASS,
|
Pass.LAST_PASS,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme
|
|||||||
|
|
||||||
class RainbowColorsSchemeListener : EditorColorsListener {
|
class RainbowColorsSchemeListener : EditorColorsListener {
|
||||||
|
|
||||||
override fun globalSchemeChange(scheme: EditorColorsScheme?) {
|
override fun globalSchemeChange(scheme: EditorColorsScheme?) {
|
||||||
scheme?.let { RainbowHighlighter.fixHighlighting(it) }
|
scheme?.let { RainbowHighlighter.fixHighlighting(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,6 +7,6 @@ import com.intellij.lang.BracePair
|
|||||||
* [BracePairProvider.blackList] for the PSI elements should NOT be a pair, so we won't rainbow-ify them.
|
* [BracePairProvider.blackList] for the PSI elements should NOT be a pair, so we won't rainbow-ify them.
|
||||||
*/
|
*/
|
||||||
interface BracePairProvider {
|
interface BracePairProvider {
|
||||||
fun pairs(): List<BracePair> = emptyList()
|
fun pairs(): List<BracePair> = emptyList()
|
||||||
fun blackList(): List<BracePair> = emptyList()
|
fun blackList(): List<BracePair> = emptyList()
|
||||||
}
|
}
|
@ -1,21 +1,18 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets.provider
|
package com.github.izhangzhihao.rainbow.brackets.provider
|
||||||
|
|
||||||
import com.intellij.lang.BracePair
|
import com.intellij.lang.BracePair
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType
|
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.GT
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.GT
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LBRACE
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LBRACE
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LBRACKET
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LBRACKET
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LPARENTH
|
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LT
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LT
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.RBRACE
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.RBRACE
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.RBRACKET
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.RBRACKET
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.RPARENTH
|
|
||||||
|
|
||||||
class CSharpBracePairProvider : BracePairProvider {
|
class CSharpBracePairProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(
|
override fun pairs(): List<BracePair> = listOf(
|
||||||
//BracePair(LPARENTH, RPARENTH, false),
|
//BracePair(LPARENTH, RPARENTH, false),
|
||||||
BracePair(LBRACE, RBRACE, false),
|
BracePair(LBRACE, RBRACE, false),
|
||||||
BracePair(LBRACKET, RBRACKET, false),
|
BracePair(LBRACKET, RBRACKET, false),
|
||||||
BracePair(LT, GT, false),
|
BracePair(LT, GT, false),
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -5,5 +5,5 @@ import com.jetbrains.lang.dart.DartTokenTypes.GT
|
|||||||
import com.jetbrains.lang.dart.DartTokenTypes.LT
|
import com.jetbrains.lang.dart.DartTokenTypes.LT
|
||||||
|
|
||||||
class DartBracePairProvider : BracePairProvider {
|
class DartBracePairProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(BracePair(LT, GT, false))
|
override fun pairs(): List<BracePair> = listOf(BracePair(LT, GT, false))
|
||||||
}
|
}
|
@ -1,11 +1,14 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets.provider
|
package com.github.izhangzhihao.rainbow.brackets.provider
|
||||||
|
|
||||||
import com.goide.template.GoTemplateTypes.*
|
import com.goide.template.GoTemplateTypes.LDOUBLE_BRACE
|
||||||
|
import com.goide.template.GoTemplateTypes.LPAREN
|
||||||
|
import com.goide.template.GoTemplateTypes.RDOUBLE_BRACE
|
||||||
|
import com.goide.template.GoTemplateTypes.RPAREN
|
||||||
import com.intellij.lang.BracePair
|
import com.intellij.lang.BracePair
|
||||||
|
|
||||||
class GoTemplateProvider : BracePairProvider {
|
class GoTemplateProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(
|
override fun pairs(): List<BracePair> = listOf(
|
||||||
BracePair(LDOUBLE_BRACE, RDOUBLE_BRACE, true),
|
BracePair(LDOUBLE_BRACE, RDOUBLE_BRACE, true),
|
||||||
BracePair(LPAREN, RPAREN, true)
|
BracePair(LPAREN, RPAREN, true)
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -5,5 +5,5 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mGT
|
|||||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mLT
|
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mLT
|
||||||
|
|
||||||
class GroovyBracePairProvider : BracePairProvider {
|
class GroovyBracePairProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(BracePair(mLT, mGT, false))
|
override fun pairs(): List<BracePair> = listOf(BracePair(mLT, mGT, false))
|
||||||
}
|
}
|
@ -6,5 +6,5 @@ import org.jetbrains.kotlin.lexer.KtTokens.LT
|
|||||||
|
|
||||||
|
|
||||||
class KotlinBracePairProvider : BracePairProvider {
|
class KotlinBracePairProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(BracePair(LT, GT, false))
|
override fun pairs(): List<BracePair> = listOf(BracePair(LT, GT, false))
|
||||||
}
|
}
|
@ -4,5 +4,5 @@ import com.intellij.lang.BracePair
|
|||||||
import com.jetbrains.cidr.lang.parser.OCTokenTypes
|
import com.jetbrains.cidr.lang.parser.OCTokenTypes
|
||||||
|
|
||||||
class OCBracePairProvider : BracePairProvider {
|
class OCBracePairProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(BracePair(OCTokenTypes.LT, OCTokenTypes.GT, false))
|
override fun pairs(): List<BracePair> = listOf(BracePair(OCTokenTypes.LT, OCTokenTypes.GT, false))
|
||||||
}
|
}
|
@ -5,8 +5,8 @@ import com.jetbrains.php.lang.lexer.PhpTokenTypes
|
|||||||
|
|
||||||
// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/423
|
// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/423
|
||||||
class PHPBracePairProvider : BracePairProvider {
|
class PHPBracePairProvider : BracePairProvider {
|
||||||
override fun blackList(): List<BracePair> = listOf(
|
override fun blackList(): List<BracePair> = listOf(
|
||||||
BracePair(PhpTokenTypes.PHP_OPENING_TAG, PhpTokenTypes.PHP_CLOSING_TAG, false),
|
BracePair(PhpTokenTypes.PHP_OPENING_TAG, PhpTokenTypes.PHP_CLOSING_TAG, false),
|
||||||
BracePair(PhpTokenTypes.PHP_ECHO_OPENING_TAG, PhpTokenTypes.PHP_CLOSING_TAG, false)
|
BracePair(PhpTokenTypes.PHP_ECHO_OPENING_TAG, PhpTokenTypes.PHP_CLOSING_TAG, false)
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -4,10 +4,10 @@ import com.intellij.lang.BracePair
|
|||||||
import com.intellij.sh.ShTypes
|
import com.intellij.sh.ShTypes
|
||||||
|
|
||||||
class SHBracePairProvider : BracePairProvider {
|
class SHBracePairProvider : BracePairProvider {
|
||||||
override fun blackList(): List<BracePair> = listOf(
|
override fun blackList(): List<BracePair> = listOf(
|
||||||
BracePair(ShTypes.HEREDOC_MARKER_START, ShTypes.HEREDOC_MARKER_END, false),
|
BracePair(ShTypes.HEREDOC_MARKER_START, ShTypes.HEREDOC_MARKER_END, false),
|
||||||
BracePair(ShTypes.DO, ShTypes.DONE, true),
|
BracePair(ShTypes.DO, ShTypes.DONE, true),
|
||||||
BracePair(ShTypes.IF, ShTypes.FI, true),
|
BracePair(ShTypes.IF, ShTypes.FI, true),
|
||||||
BracePair(ShTypes.CASE, ShTypes.ESAC, true)
|
BracePair(ShTypes.CASE, ShTypes.ESAC, true)
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -6,8 +6,8 @@ import com.intellij.sql.psi.SqlTokens.SQL_BEGIN
|
|||||||
import com.intellij.sql.psi.SqlTokens.SQL_END
|
import com.intellij.sql.psi.SqlTokens.SQL_END
|
||||||
|
|
||||||
class SqlBracePairProvider : BracePairProvider {
|
class SqlBracePairProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(
|
override fun pairs(): List<BracePair> = listOf(
|
||||||
BracePair(SQL_BEGIN, SQL_END, false),
|
BracePair(SQL_BEGIN, SQL_END, false),
|
||||||
BracePair(SQL_CASE, SQL_END, false),
|
BracePair(SQL_CASE, SQL_END, false),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,5 @@ import com.intellij.lang.javascript.JSTokenTypes.GT
|
|||||||
import com.intellij.lang.javascript.JSTokenTypes.LT
|
import com.intellij.lang.javascript.JSTokenTypes.LT
|
||||||
|
|
||||||
class TSBracePairProvider : BracePairProvider {
|
class TSBracePairProvider : BracePairProvider {
|
||||||
override fun pairs(): List<BracePair> = listOf(BracePair(LT, GT, false))
|
override fun pairs(): List<BracePair> = listOf(BracePair(LT, GT, false))
|
||||||
}
|
}
|
@ -2,7 +2,12 @@ package com.github.izhangzhihao.rainbow.brackets.settings
|
|||||||
|
|
||||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
||||||
import com.github.izhangzhihao.rainbow.brackets.settings.form.RainbowOptionsPanel
|
import com.github.izhangzhihao.rainbow.brackets.settings.form.RainbowOptionsPanel
|
||||||
import com.intellij.application.options.colors.*
|
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.AttributesDescriptor
|
||||||
import com.intellij.openapi.options.colors.ColorAndFontDescriptorsProvider
|
import com.intellij.openapi.options.colors.ColorAndFontDescriptorsProvider
|
||||||
import com.intellij.openapi.options.colors.ColorDescriptor
|
import com.intellij.openapi.options.colors.ColorDescriptor
|
||||||
@ -12,44 +17,44 @@ import com.intellij.psi.codeStyle.DisplayPrioritySortable
|
|||||||
|
|
||||||
class RainbowColorsPageFactory : ColorAndFontPanelFactory, ColorAndFontDescriptorsProvider, DisplayPrioritySortable {
|
class RainbowColorsPageFactory : ColorAndFontPanelFactory, ColorAndFontDescriptorsProvider, DisplayPrioritySortable {
|
||||||
|
|
||||||
override fun getDisplayName(): String = RAINBOW_BRACKETS_GROUP
|
override fun getDisplayName(): String = RAINBOW_BRACKETS_GROUP
|
||||||
|
|
||||||
override fun getPanelDisplayName(): String = RAINBOW_BRACKETS_GROUP
|
override fun getPanelDisplayName(): String = RAINBOW_BRACKETS_GROUP
|
||||||
|
|
||||||
override fun getPriority(): DisplayPriority = DisplayPriority.COMMON_SETTINGS
|
override fun getPriority(): DisplayPriority = DisplayPriority.COMMON_SETTINGS
|
||||||
|
|
||||||
override fun createPanel(options: ColorAndFontOptions): NewColorAndFontPanel {
|
override fun createPanel(options: ColorAndFontOptions): NewColorAndFontPanel {
|
||||||
val emptyPreview = PreviewPanel.Empty()
|
val emptyPreview = PreviewPanel.Empty()
|
||||||
val schemesPanel = SchemesPanel(options)
|
val schemesPanel = SchemesPanel(options)
|
||||||
val optionsPanel = RainbowOptionsPanel(options, schemesPanel, RAINBOW_BRACKETS_GROUP)
|
val optionsPanel = RainbowOptionsPanel(options, schemesPanel, RAINBOW_BRACKETS_GROUP)
|
||||||
|
|
||||||
schemesPanel.addListener(object : ColorAndFontSettingsListener.Abstract() {
|
schemesPanel.addListener(object : ColorAndFontSettingsListener.Abstract() {
|
||||||
override fun schemeChanged(source: Any) {
|
override fun schemeChanged(source: Any) {
|
||||||
optionsPanel.updateOptionsList()
|
optionsPanel.updateOptionsList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return NewColorAndFontPanel(schemesPanel, optionsPanel, emptyPreview, RAINBOW_BRACKETS_GROUP, null, null)
|
return NewColorAndFontPanel(schemesPanel, optionsPanel, emptyPreview, RAINBOW_BRACKETS_GROUP, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttributeDescriptors(): Array<AttributesDescriptor> = ATTRIBUTE_DESCRIPTORS
|
override fun getAttributeDescriptors(): Array<AttributesDescriptor> = ATTRIBUTE_DESCRIPTORS
|
||||||
|
|
||||||
override fun getColorDescriptors(): Array<ColorDescriptor> = emptyArray()
|
override fun getColorDescriptors(): Array<ColorDescriptor> = emptyArray()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val RAINBOW_BRACKETS_GROUP = "Rainbow Brackets"
|
private const val RAINBOW_BRACKETS_GROUP = "Colored Brackets"
|
||||||
private val ATTRIBUTE_DESCRIPTORS: Array<AttributesDescriptor> by lazy {
|
private val ATTRIBUTE_DESCRIPTORS: Array<AttributesDescriptor> by lazy {
|
||||||
createDescriptors(RainbowHighlighter.NAME_ROUND_BRACKETS) +
|
createDescriptors(RainbowHighlighter.NAME_ROUND_BRACKETS) +
|
||||||
createDescriptors(RainbowHighlighter.NAME_SQUARE_BRACKETS) +
|
createDescriptors(RainbowHighlighter.NAME_SQUARE_BRACKETS) +
|
||||||
createDescriptors(RainbowHighlighter.NAME_SQUIGGLY_BRACKETS) +
|
createDescriptors(RainbowHighlighter.NAME_SQUIGGLY_BRACKETS) +
|
||||||
createDescriptors(RainbowHighlighter.NAME_ANGLE_BRACKETS)
|
createDescriptors(RainbowHighlighter.NAME_ANGLE_BRACKETS)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDescriptors(name: String): Array<AttributesDescriptor> {
|
private fun createDescriptors(name: String): Array<AttributesDescriptor> {
|
||||||
return RainbowHighlighter.getRainbowAttributesKeys(name)
|
return RainbowHighlighter.getRainbowAttributesKeys(name)
|
||||||
.map { key -> AttributesDescriptor("$name:$key", key) }
|
.map { key -> AttributesDescriptor("$name:$key", key) }
|
||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -7,60 +7,60 @@ import org.jetbrains.annotations.Nls
|
|||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
|
|
||||||
class RainbowConfigurable : SearchableConfigurable {
|
class RainbowConfigurable : SearchableConfigurable {
|
||||||
private var settingsForm: RainbowSettingsForm? = null
|
private var settingsForm: RainbowSettingsForm? = null
|
||||||
|
|
||||||
override fun createComponent(): JComponent? {
|
override fun createComponent(): JComponent? {
|
||||||
settingsForm = settingsForm ?: RainbowSettingsForm()
|
settingsForm = settingsForm ?: RainbowSettingsForm()
|
||||||
return settingsForm?.component()
|
return settingsForm?.component()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isModified(): Boolean {
|
override fun isModified(): Boolean {
|
||||||
return settingsForm?.isModified ?: return false
|
return settingsForm?.isModified ?: return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
override fun apply() {
|
override fun apply() {
|
||||||
val settings = RainbowSettings.instance
|
val settings = RainbowSettings.instance
|
||||||
settings.isRainbowEnabled = settingsForm?.isRainbowEnabled() ?: true
|
settings.isRainbowEnabled = settingsForm?.isRainbowEnabled() ?: true
|
||||||
settings.isEnableRainbowRoundBrackets = settingsForm?.isRainbowRoundBracketsEnabled() ?: true
|
settings.isEnableRainbowRoundBrackets = settingsForm?.isRainbowRoundBracketsEnabled() ?: true
|
||||||
settings.isEnableRainbowAngleBrackets = settingsForm?.isRainbowAngleBracketsEnabled() ?: true
|
settings.isEnableRainbowAngleBrackets = settingsForm?.isRainbowAngleBracketsEnabled() ?: true
|
||||||
settings.isEnableRainbowSquigglyBrackets = settingsForm?.isRainbowSquigglyBracketsEnabled() ?: true
|
settings.isEnableRainbowSquigglyBrackets = settingsForm?.isRainbowSquigglyBracketsEnabled() ?: true
|
||||||
settings.isEnableRainbowSquareBrackets = settingsForm?.isRainbowSquareBracketsEnabled() ?: true
|
settings.isEnableRainbowSquareBrackets = settingsForm?.isRainbowSquareBracketsEnabled() ?: true
|
||||||
settings.isShowRainbowIndentGuides = settingsForm?.isShowRainbowIndentGuides() ?: false
|
settings.isShowRainbowIndentGuides = settingsForm?.isShowRainbowIndentGuides() ?: false
|
||||||
settings.isDoNOTRainbowifyBracketsWithoutContent = settingsForm?.isDoNOTRainbowifyBracketsWithoutContent()
|
settings.isDoNOTRainbowifyBracketsWithoutContent = settingsForm?.isDoNOTRainbowifyBracketsWithoutContent()
|
||||||
?: false
|
?: false
|
||||||
settings.isDoNOTRainbowifyTheFirstLevel = settingsForm?.isDoNOTRainbowifyTheFirstLevel() ?: false
|
settings.isDoNOTRainbowifyTheFirstLevel = settingsForm?.isDoNOTRainbowifyTheFirstLevel() ?: false
|
||||||
settings.pressAnyKeyToRemoveTheHighlightingEffects = settingsForm?.pressAnyKeyToRemoveTheHighlightingEffects()
|
settings.pressAnyKeyToRemoveTheHighlightingEffects = settingsForm?.pressAnyKeyToRemoveTheHighlightingEffects()
|
||||||
?: false
|
?: false
|
||||||
settings.applyColorsOfRoundForAllBrackets = settingsForm?.applyColorsOfRoundForAllBrackets()
|
settings.applyColorsOfRoundForAllBrackets = settingsForm?.applyColorsOfRoundForAllBrackets()
|
||||||
?: false
|
?: false
|
||||||
settings.cycleCountOnAllBrackets = settingsForm?.cycleCountOnAllBrackets()
|
settings.cycleCountOnAllBrackets = settingsForm?.cycleCountOnAllBrackets()
|
||||||
?: false
|
?: false
|
||||||
settings.numberOfColors = settingsForm?.numberOfColors() ?: 5
|
settings.numberOfColors = settingsForm?.numberOfColors() ?: 5
|
||||||
settings.languageBlacklist = settingsForm?.languageBlacklist() ?: emptySet()
|
settings.languageBlacklist = settingsForm?.languageBlacklist() ?: emptySet()
|
||||||
settings.disableRainbowIndentsInZenMode = settingsForm?.disableRainbowIndentsInZenMode() ?: true
|
settings.disableRainbowIndentsInZenMode = settingsForm?.disableRainbowIndentsInZenMode() ?: true
|
||||||
settings.useColorGenerator = settingsForm?.useColorGenerator() ?: false
|
settings.useColorGenerator = settingsForm?.useColorGenerator() ?: false
|
||||||
settings.rainbowifyTagNameInXML = settingsForm?.rainbowifyTagNameInXML() ?: false
|
settings.rainbowifyTagNameInXML = settingsForm?.rainbowifyTagNameInXML() ?: false
|
||||||
settings.doNOTRainbowifyTemplateString = settingsForm?.doNOTRainbowifyTemplateString() ?: false
|
settings.doNOTRainbowifyTemplateString = settingsForm?.doNOTRainbowifyTemplateString() ?: false
|
||||||
settings.doNOTRainbowifyBigFiles = settingsForm?.doNOTRainbowifyBigFiles() ?: true
|
settings.doNOTRainbowifyBigFiles = settingsForm?.doNOTRainbowifyBigFiles() ?: true
|
||||||
settings.bigFilesLinesThreshold = settingsForm?.bigFilesLinesThreshold() ?: 1000
|
settings.bigFilesLinesThreshold = settingsForm?.bigFilesLinesThreshold() ?: 1000
|
||||||
settings.rainbowifyPythonKeywords = settingsForm?.rainbowifyPythonKeywords() ?: false
|
settings.rainbowifyPythonKeywords = settingsForm?.rainbowifyPythonKeywords() ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reset() {
|
override fun reset() {
|
||||||
settingsForm?.loadSettings()
|
settingsForm?.loadSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun disposeUIResources() {
|
override fun disposeUIResources() {
|
||||||
settingsForm = null
|
settingsForm = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nls
|
@Nls
|
||||||
override fun getDisplayName() = "Rainbow Brackets"
|
override fun getDisplayName() = "Colored Brackets"
|
||||||
|
|
||||||
override fun getId(): String = ID
|
override fun getId(): String = ID
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val ID = "preferences.rainbow.brackets"
|
const val ID = "preferences.rainbow.brackets"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,54 +10,52 @@ import org.jetbrains.annotations.Nullable
|
|||||||
|
|
||||||
@State(name = "RainbowSettings", storages = [(Storage("rainbow_brackets.xml"))])
|
@State(name = "RainbowSettings", storages = [(Storage("rainbow_brackets.xml"))])
|
||||||
class RainbowSettings : PersistentStateComponent<RainbowSettings> {
|
class RainbowSettings : PersistentStateComponent<RainbowSettings> {
|
||||||
/**
|
/**
|
||||||
* default value
|
* default value
|
||||||
*/
|
*/
|
||||||
var isRainbowEnabled = true
|
var isRainbowEnabled = true
|
||||||
var isEnableRainbowRoundBrackets = true
|
var isEnableRainbowRoundBrackets = true
|
||||||
var isEnableRainbowSquigglyBrackets = true
|
var isEnableRainbowSquigglyBrackets = true
|
||||||
var isEnableRainbowSquareBrackets = true
|
var isEnableRainbowSquareBrackets = true
|
||||||
var isEnableRainbowAngleBrackets = true
|
var isEnableRainbowAngleBrackets = true
|
||||||
var isShowRainbowIndentGuides = true
|
var isShowRainbowIndentGuides = true
|
||||||
var isDoNOTRainbowifyBracketsWithoutContent = false
|
var isDoNOTRainbowifyBracketsWithoutContent = false
|
||||||
var isDoNOTRainbowifyTheFirstLevel = false
|
var isDoNOTRainbowifyTheFirstLevel = false
|
||||||
var version = "Unknown"
|
var isRainbowifyHTMLInsideJS = true
|
||||||
var isRainbowifyHTMLInsideJS = true
|
var isRainbowifyKotlinLabel = true
|
||||||
var isRainbowifyKotlinLabel = true
|
var isRainbowifyKotlinFunctionLiteralBracesAndArrow = true
|
||||||
var isRainbowifyKotlinFunctionLiteralBracesAndArrow = true
|
var isOverrideMatchedBraceAttributes = true
|
||||||
var isOverrideMatchedBraceAttributes = true
|
var pressAnyKeyToRemoveTheHighlightingEffects = false
|
||||||
var pressAnyKeyToRemoveTheHighlightingEffects = false
|
var applyColorsOfRoundForAllBrackets = false
|
||||||
var applyColorsOfRoundForAllBrackets = false
|
|
||||||
|
|
||||||
//https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/391
|
//https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/391
|
||||||
var cycleCountOnAllBrackets = false
|
var cycleCountOnAllBrackets = false
|
||||||
var numberOfColors = 5
|
var numberOfColors = 5
|
||||||
|
|
||||||
var disableRainbowIndentsInZenMode = true
|
var disableRainbowIndentsInZenMode = true
|
||||||
var useColorGenerator = false
|
var useColorGenerator = false
|
||||||
var customColorGeneratorOption: String? = null
|
var customColorGeneratorOption: String? = null
|
||||||
var showNotificationOnUpdate = true
|
var rainbowifyTagNameInXML = false
|
||||||
var rainbowifyTagNameInXML = false
|
var doNOTRainbowifyTemplateString = false
|
||||||
var doNOTRainbowifyTemplateString = false
|
var doNOTRainbowifyBigFiles = true
|
||||||
var doNOTRainbowifyBigFiles = true
|
var bigFilesLinesThreshold = 1000
|
||||||
var bigFilesLinesThreshold = 1000
|
|
||||||
|
|
||||||
var languageBlacklist: Set<String> = setOf("hocon", "mxml")
|
var languageBlacklist: Set<String> = setOf("hocon", "mxml")
|
||||||
|
|
||||||
var suppressDisabledCheck = false
|
var suppressDisabledCheck = false
|
||||||
var suppressBigFileCheck = false
|
var suppressBigFileCheck = false
|
||||||
var suppressBlackListCheck = false
|
var suppressBlackListCheck = false
|
||||||
var rainbowifyPythonKeywords = false
|
var rainbowifyPythonKeywords = false
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
override fun getState() = this
|
override fun getState() = this
|
||||||
|
|
||||||
override fun loadState(state: RainbowSettings) {
|
override fun loadState(state: RainbowSettings) {
|
||||||
copyBean(state, this)
|
copyBean(state, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val instance: RainbowSettings
|
val instance: RainbowSettings
|
||||||
get() = ApplicationManager.getApplication().getService(RainbowSettings::class.java)
|
get() = ApplicationManager.getApplication().getService(RainbowSettings::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,11 @@ package com.github.izhangzhihao.rainbow.brackets.settings.form
|
|||||||
|
|
||||||
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
import com.github.izhangzhihao.rainbow.brackets.RainbowHighlighter
|
||||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
||||||
import com.intellij.application.options.colors.*
|
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.ide.util.PropertiesComponent
|
||||||
import com.intellij.ui.ColorPanel
|
import com.intellij.ui.ColorPanel
|
||||||
import com.intellij.ui.components.JBCheckBox
|
import com.intellij.ui.components.JBCheckBox
|
||||||
@ -20,243 +24,247 @@ import javax.swing.tree.TreeSelectionModel
|
|||||||
|
|
||||||
|
|
||||||
class RainbowOptionsPanel(
|
class RainbowOptionsPanel(
|
||||||
private val options: ColorAndFontOptions,
|
private val options: ColorAndFontOptions,
|
||||||
private val schemesProvider: SchemesPanel,
|
private val schemesProvider: SchemesPanel,
|
||||||
private val category: String
|
private val category: String,
|
||||||
) : OptionsPanel {
|
) : OptionsPanel {
|
||||||
|
|
||||||
private lateinit var rootPanel: JPanel
|
private lateinit var rootPanel: JPanel
|
||||||
private lateinit var optionsTree: Tree
|
private lateinit var optionsTree: Tree
|
||||||
|
|
||||||
private lateinit var rainbow: JBCheckBox
|
private lateinit var rainbow: JBCheckBox
|
||||||
|
|
||||||
private lateinit var colorLabel1: JLabel
|
private lateinit var colorLabel1: JLabel
|
||||||
private lateinit var colorLabel2: JLabel
|
private lateinit var colorLabel2: JLabel
|
||||||
private lateinit var colorLabel3: JLabel
|
private lateinit var colorLabel3: JLabel
|
||||||
private lateinit var colorLabel4: JLabel
|
private lateinit var colorLabel4: JLabel
|
||||||
private lateinit var colorLabel5: JLabel
|
private lateinit var colorLabel5: JLabel
|
||||||
|
|
||||||
private val colorLabels: Array<JLabel>
|
private val colorLabels: Array<JLabel>
|
||||||
|
|
||||||
private lateinit var color1: ColorPanel
|
private lateinit var color1: ColorPanel
|
||||||
private lateinit var color2: ColorPanel
|
private lateinit var color2: ColorPanel
|
||||||
private lateinit var color3: ColorPanel
|
private lateinit var color3: ColorPanel
|
||||||
private lateinit var color4: ColorPanel
|
private lateinit var color4: ColorPanel
|
||||||
private lateinit var color5: ColorPanel
|
private lateinit var color5: ColorPanel
|
||||||
|
|
||||||
private val colors: Array<ColorPanel>
|
private val colors: Array<ColorPanel>
|
||||||
|
|
||||||
private lateinit var gradientLabel: JLabel
|
private lateinit var gradientLabel: JLabel
|
||||||
|
|
||||||
private val properties: PropertiesComponent = PropertiesComponent.getInstance()
|
private val properties: PropertiesComponent = PropertiesComponent.getInstance()
|
||||||
private val eventDispatcher: EventDispatcher<ColorAndFontSettingsListener> =
|
private val eventDispatcher: EventDispatcher<ColorAndFontSettingsListener> =
|
||||||
EventDispatcher.create(ColorAndFontSettingsListener::class.java)
|
EventDispatcher.create(ColorAndFontSettingsListener::class.java)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
colors = arrayOf(color1, color2, color3, color4, color5)
|
colors = arrayOf(color1, color2, color3, color4, color5)
|
||||||
colorLabels = arrayOf(colorLabel1, colorLabel2, colorLabel3, colorLabel4, colorLabel5)
|
colorLabels = arrayOf(colorLabel1, colorLabel2, colorLabel3, colorLabel4, colorLabel5)
|
||||||
|
|
||||||
val actionListener = ActionListener {
|
val actionListener = ActionListener {
|
||||||
eventDispatcher.multicaster.settingsChanged()
|
eventDispatcher.multicaster.settingsChanged()
|
||||||
options.stateChanged()
|
options.stateChanged()
|
||||||
}
|
}
|
||||||
rainbow.addActionListener(actionListener)
|
rainbow.addActionListener(actionListener)
|
||||||
for (c in colors) {
|
for (c in colors) {
|
||||||
c.addActionListener(actionListener)
|
c.addActionListener(actionListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
options.addListener(object : ColorAndFontSettingsListener.Abstract() {
|
options.addListener(object : ColorAndFontSettingsListener.Abstract() {
|
||||||
override fun settingsChanged() {
|
override fun settingsChanged() {
|
||||||
if (!schemesProvider.areSchemesLoaded()) return
|
if (!schemesProvider.areSchemesLoaded()) return
|
||||||
if (optionsTree.selectedValue != null) {
|
if (optionsTree.selectedValue != null) {
|
||||||
// update options after global state change
|
// update options after global state change
|
||||||
processListValueChanged()
|
processListValueChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
optionsTree.apply {
|
optionsTree.apply {
|
||||||
isRootVisible = false
|
isRootVisible = false
|
||||||
model = DefaultTreeModel(DefaultMutableTreeTableNode())
|
model = DefaultTreeModel(DefaultMutableTreeTableNode())
|
||||||
selectionModel.selectionMode = TreeSelectionModel.SINGLE_TREE_SELECTION
|
selectionModel.selectionMode = TreeSelectionModel.SINGLE_TREE_SELECTION
|
||||||
addTreeSelectionListener {
|
addTreeSelectionListener {
|
||||||
if (schemesProvider.areSchemesLoaded()) {
|
if (schemesProvider.areSchemesLoaded()) {
|
||||||
processListValueChanged()
|
processListValueChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPanel(): JPanel = rootPanel
|
override fun getPanel(): JPanel = rootPanel
|
||||||
|
|
||||||
override fun addListener(listener: ColorAndFontSettingsListener) {
|
override fun addListener(listener: ColorAndFontSettingsListener) {
|
||||||
eventDispatcher.addListener(listener)
|
eventDispatcher.addListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateOptionsList() {
|
override fun updateOptionsList() {
|
||||||
fillOptionsList()
|
fillOptionsList()
|
||||||
processListValueChanged()
|
processListValueChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class DescriptionsNode(val rainbowName: String, val descriptions: List<TextAttributesDescription>) {
|
private data class DescriptionsNode(val rainbowName: String, val descriptions: List<TextAttributesDescription>) {
|
||||||
override fun toString(): String = rainbowName
|
override fun toString(): String = rainbowName
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillOptionsList() {
|
private fun fillOptionsList() {
|
||||||
val nodes = options.currentDescriptions.asSequence()
|
val nodes = options.currentDescriptions.asSequence()
|
||||||
.filter { it is TextAttributesDescription && it.group == category }
|
.filter { it is TextAttributesDescription && it.group == category }
|
||||||
.map {
|
.map {
|
||||||
val description = it as TextAttributesDescription
|
val description = it as TextAttributesDescription
|
||||||
val rainbowName = description.toString().split(":")[0]
|
val rainbowName = description.toString().split(":")[0]
|
||||||
rainbowName to description
|
rainbowName to description
|
||||||
}
|
}
|
||||||
.groupBy { it.first }
|
.groupBy { it.first }
|
||||||
.map { (rainbowName, descriptions) ->
|
.map { (rainbowName, descriptions) ->
|
||||||
DefaultMutableTreeNode(DescriptionsNode(rainbowName,
|
DefaultMutableTreeNode(
|
||||||
descriptions.asSequence().map { it.second }.toList().sortedBy { it.toString() }))
|
DescriptionsNode(
|
||||||
}
|
rainbowName,
|
||||||
val root = DefaultMutableTreeNode()
|
descriptions.asSequence().map { it.second }.toList().sortedBy { it.toString() })
|
||||||
for (node in nodes) {
|
)
|
||||||
root.add(node)
|
}
|
||||||
}
|
val root = DefaultMutableTreeNode()
|
||||||
|
for (node in nodes) {
|
||||||
|
root.add(node)
|
||||||
|
}
|
||||||
|
|
||||||
(optionsTree.model as DefaultTreeModel).setRoot(root)
|
(optionsTree.model as DefaultTreeModel).setRoot(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processListValueChanged() {
|
private fun processListValueChanged() {
|
||||||
var descriptionsNode = optionsTree.selectedDescriptions
|
var descriptionsNode = optionsTree.selectedDescriptions
|
||||||
if (descriptionsNode == null) {
|
if (descriptionsNode == null) {
|
||||||
properties.getValue(SELECTED_COLOR_OPTION_PROPERTY)?.let { preselected ->
|
properties.getValue(SELECTED_COLOR_OPTION_PROPERTY)?.let { preselected ->
|
||||||
optionsTree.selectOptionByRainbowName(preselected)
|
optionsTree.selectOptionByRainbowName(preselected)
|
||||||
descriptionsNode = optionsTree.selectedDescriptions
|
descriptionsNode = optionsTree.selectedDescriptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptionsNode?.run {
|
descriptionsNode?.run {
|
||||||
properties.setValue(SELECTED_COLOR_OPTION_PROPERTY, rainbowName)
|
properties.setValue(SELECTED_COLOR_OPTION_PROPERTY, rainbowName)
|
||||||
reset(rainbowName, descriptions)
|
reset(rainbowName, descriptions)
|
||||||
} ?: resetDefault()
|
} ?: resetDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetDefault() {
|
private fun resetDefault() {
|
||||||
rainbow.isEnabled = false
|
rainbow.isEnabled = false
|
||||||
rainbow.isSelected = false
|
rainbow.isSelected = false
|
||||||
gradientLabel.text = "Assign each brackets its own color from the spectrum below:"
|
gradientLabel.text = "Assign each brackets its own color from the spectrum below:"
|
||||||
|
|
||||||
for (i in 0 until minRange()) {
|
for (i in 0 until minRange()) {
|
||||||
colors[i].isEnabled = false
|
colors[i].isEnabled = false
|
||||||
colors[i].selectedColor = null
|
colors[i].selectedColor = null
|
||||||
colorLabels[i].isEnabled = false
|
colorLabels[i].isEnabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reset(rainbowName: String, descriptions: List<TextAttributesDescription>) {
|
private fun reset(rainbowName: String, descriptions: List<TextAttributesDescription>) {
|
||||||
val rainbowOn = RainbowHighlighter.isRainbowEnabled(rainbowName)
|
val rainbowOn = RainbowHighlighter.isRainbowEnabled(rainbowName)
|
||||||
|
|
||||||
rainbow.isEnabled = true
|
rainbow.isEnabled = true
|
||||||
rainbow.isSelected = rainbowOn
|
rainbow.isSelected = rainbowOn
|
||||||
gradientLabel.text = "Assign each ${rainbowName.toLowerCase()} its own color from the spectrum below:"
|
gradientLabel.text = "Assign each ${rainbowName.lowercase()} its own color from the spectrum below:"
|
||||||
|
|
||||||
for (i in 0 until minRange()) {
|
for (i in 0 until minRange()) {
|
||||||
colors[i].isEnabled = rainbowOn
|
colors[i].isEnabled = rainbowOn
|
||||||
colorLabels[i].isEnabled = rainbowOn
|
colorLabels[i].isEnabled = rainbowOn
|
||||||
colors[i].selectedColor = descriptions.indexOfOrNull(i)?.rainbowColor
|
colors[i].selectedColor = descriptions.indexOfOrNull(i)?.rainbowColor
|
||||||
descriptions.indexOfOrNull(i)?.let { eventDispatcher.multicaster.selectedOptionChanged(it) }
|
descriptions.indexOfOrNull(i)?.let { eventDispatcher.multicaster.selectedOptionChanged(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun applyChangesToScheme() {
|
override fun applyChangesToScheme() {
|
||||||
val scheme = options.selectedScheme
|
val scheme = options.selectedScheme
|
||||||
val (rainbowName, descriptions) = optionsTree.selectedDescriptions ?: return
|
val (rainbowName, descriptions) = optionsTree.selectedDescriptions ?: return
|
||||||
when (rainbowName) {
|
when (rainbowName) {
|
||||||
RainbowHighlighter.NAME_ROUND_BRACKETS,
|
RainbowHighlighter.NAME_ROUND_BRACKETS,
|
||||||
RainbowHighlighter.NAME_ANGLE_BRACKETS,
|
RainbowHighlighter.NAME_ANGLE_BRACKETS,
|
||||||
RainbowHighlighter.NAME_SQUARE_BRACKETS,
|
RainbowHighlighter.NAME_SQUARE_BRACKETS,
|
||||||
RainbowHighlighter.NAME_SQUIGGLY_BRACKETS -> {
|
RainbowHighlighter.NAME_SQUIGGLY_BRACKETS,
|
||||||
RainbowHighlighter.setRainbowEnabled(rainbowName, rainbow.isSelected)
|
-> {
|
||||||
|
RainbowHighlighter.setRainbowEnabled(rainbowName, rainbow.isSelected)
|
||||||
|
|
||||||
for (i in 0 until minRange()) {
|
for (i in 0 until minRange()) {
|
||||||
colors[i].selectedColor?.let { color ->
|
colors[i].selectedColor?.let { color ->
|
||||||
descriptions[i].rainbowColor = color
|
descriptions[i].rainbowColor = color
|
||||||
descriptions[i].apply(scheme)
|
descriptions[i].apply(scheme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun minRange() = minOf(RainbowSettings.instance.numberOfColors, 5)
|
private fun minRange() = minOf(RainbowSettings.instance.numberOfColors, 5)
|
||||||
|
|
||||||
override fun processListOptions(): MutableSet<String> = mutableSetOf(
|
override fun processListOptions(): MutableSet<String> = mutableSetOf(
|
||||||
RainbowHighlighter.NAME_ROUND_BRACKETS,
|
RainbowHighlighter.NAME_ROUND_BRACKETS,
|
||||||
RainbowHighlighter.NAME_SQUARE_BRACKETS,
|
RainbowHighlighter.NAME_SQUARE_BRACKETS,
|
||||||
RainbowHighlighter.NAME_SQUIGGLY_BRACKETS,
|
RainbowHighlighter.NAME_SQUIGGLY_BRACKETS,
|
||||||
RainbowHighlighter.NAME_ANGLE_BRACKETS
|
RainbowHighlighter.NAME_ANGLE_BRACKETS
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun showOption(option: String): Runnable? = Runnable {
|
override fun showOption(option: String) = Runnable {
|
||||||
optionsTree.selectOptionByRainbowName(option)
|
optionsTree.selectOptionByRainbowName(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun selectOption(typeToSelect: String) {
|
override fun selectOption(typeToSelect: String) {
|
||||||
optionsTree.selectOptionByType(typeToSelect)
|
optionsTree.selectOptionByType(typeToSelect)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val SELECTED_COLOR_OPTION_PROPERTY = "rainbow.selected.color.option.name"
|
private const val SELECTED_COLOR_OPTION_PROPERTY = "rainbow.selected.color.option.name"
|
||||||
|
|
||||||
private var TextAttributesDescription.rainbowColor: Color?
|
private var TextAttributesDescription.rainbowColor: Color?
|
||||||
get() = externalForeground
|
get() = externalForeground
|
||||||
set(value) {
|
set(value) {
|
||||||
externalForeground = value
|
externalForeground = value
|
||||||
}
|
}
|
||||||
|
|
||||||
private val Tree.selectedValue: Any?
|
private val Tree.selectedValue: Any?
|
||||||
get() = (lastSelectedPathComponent as? DefaultMutableTreeNode)?.userObject
|
get() = (lastSelectedPathComponent as? DefaultMutableTreeNode)?.userObject
|
||||||
|
|
||||||
private val Tree.selectedDescriptions: DescriptionsNode?
|
private val Tree.selectedDescriptions: DescriptionsNode?
|
||||||
get() = selectedValue as? DescriptionsNode
|
get() = selectedValue as? DescriptionsNode
|
||||||
|
|
||||||
private fun Tree.findOption(nodeObject: Any, matcher: (Any) -> Boolean): TreePath? {
|
private fun Tree.findOption(nodeObject: Any, matcher: (Any) -> Boolean): TreePath? {
|
||||||
val model = model as DefaultTreeModel
|
val model = model as DefaultTreeModel
|
||||||
for (i in 0 until model.getChildCount(nodeObject)) {
|
for (i in 0 until model.getChildCount(nodeObject)) {
|
||||||
val childObject = model.getChild(nodeObject, i)
|
val childObject = model.getChild(nodeObject, i)
|
||||||
if (childObject is DefaultMutableTreeNode) {
|
if (childObject is DefaultMutableTreeNode) {
|
||||||
val data = childObject.userObject
|
val data = childObject.userObject
|
||||||
if (matcher(data)) {
|
if (matcher(data)) {
|
||||||
return TreePath(model.getPathToRoot(childObject))
|
return TreePath(model.getPathToRoot(childObject))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val pathInChild = findOption(childObject, matcher)
|
val pathInChild = findOption(childObject, matcher)
|
||||||
if (pathInChild != null) return pathInChild
|
if (pathInChild != null) return pathInChild
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Tree.selectOptionByRainbowName(rainbowName: String) {
|
private fun Tree.selectOptionByRainbowName(rainbowName: String) {
|
||||||
selectPath(findOption(model.root) { data ->
|
selectPath(findOption(model.root) { data ->
|
||||||
data is DescriptionsNode
|
data is DescriptionsNode
|
||||||
&& rainbowName.isNotBlank()
|
&& rainbowName.isNotBlank()
|
||||||
&& data.rainbowName.contains(rainbowName, ignoreCase = true)
|
&& data.rainbowName.contains(rainbowName, ignoreCase = true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Tree.selectOptionByType(attributeType: String) {
|
private fun Tree.selectOptionByType(attributeType: String) {
|
||||||
selectPath(findOption(model.root) { data ->
|
selectPath(findOption(model.root) { data ->
|
||||||
data is DescriptionsNode && data.descriptions.any { it.type == attributeType }
|
data is DescriptionsNode && data.descriptions.any { it.type == attributeType }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Tree.selectPath(path: TreePath?) {
|
private fun Tree.selectPath(path: TreePath?) {
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
selectionPath = path
|
selectionPath = path
|
||||||
scrollPathToVisible(path)
|
scrollPathToVisible(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <E> List<E>.indexOfOrNull(idx: Int): E? = if (idx < this.size) this[idx] else null
|
private fun <E> List<E>.indexOfOrNull(idx: Int): E? = if (idx < this.size) this[idx] else null
|
@ -14,7 +14,7 @@
|
|||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties/>
|
<properties/>
|
||||||
<border type="etched" title="Rainbow Brackets"/>
|
<border type="none"/>
|
||||||
<children>
|
<children>
|
||||||
<component id="2d399" class="javax.swing.JCheckBox" binding="enableRainbow">
|
<component id="2d399" class="javax.swing.JCheckBox" binding="enableRainbow">
|
||||||
<constraints>
|
<constraints>
|
||||||
|
@ -7,131 +7,132 @@ import javax.swing.JPanel
|
|||||||
import javax.swing.JTextField
|
import javax.swing.JTextField
|
||||||
|
|
||||||
class RainbowSettingsForm {
|
class RainbowSettingsForm {
|
||||||
private var panel: JPanel? = null
|
private var panel: JPanel? = null
|
||||||
private var appearancePanel: JPanel? = null
|
@Suppress("unused")
|
||||||
private var enableRainbow: JCheckBox? = null
|
private var appearancePanel: JPanel? = null
|
||||||
private var enableRainbowRoundBrackets: JCheckBox? = null
|
private var enableRainbow: JCheckBox? = null
|
||||||
private var enableRainbowSquigglyBrackets: JCheckBox? = null
|
private var enableRainbowRoundBrackets: JCheckBox? = null
|
||||||
private var enableRainbowSquareBrackets: JCheckBox? = null
|
private var enableRainbowSquigglyBrackets: JCheckBox? = null
|
||||||
private var enableRainbowAngleBrackets: JCheckBox? = null
|
private var enableRainbowSquareBrackets: JCheckBox? = null
|
||||||
private var showRainbowIndentGuides: JCheckBox? = null
|
private var enableRainbowAngleBrackets: JCheckBox? = null
|
||||||
private var doNOTRainbowifyBracketsWithoutContent: JCheckBox? = null
|
private var showRainbowIndentGuides: JCheckBox? = null
|
||||||
private var isDoNOTRainbowifyTheFirstLevel: JCheckBox? = null
|
private var doNOTRainbowifyBracketsWithoutContent: JCheckBox? = null
|
||||||
private var pressAnyKeyToRemoveTheHighlightingEffects: JCheckBox? = null
|
private var isDoNOTRainbowifyTheFirstLevel: JCheckBox? = null
|
||||||
private var applyColorsOfRoundForAllBrackets: JCheckBox? = null
|
private var pressAnyKeyToRemoveTheHighlightingEffects: JCheckBox? = null
|
||||||
private var cycleCountOnAllBrackets: JCheckBox? = null
|
private var applyColorsOfRoundForAllBrackets: JCheckBox? = null
|
||||||
|
private var cycleCountOnAllBrackets: JCheckBox? = null
|
||||||
|
|
||||||
private var numberOfColors: JTextField? = null
|
private var numberOfColors: JTextField? = null
|
||||||
|
|
||||||
private var languageBlacklist: JTextField? = null
|
private var languageBlacklist: JTextField? = null
|
||||||
|
|
||||||
private var disableRainbowIndentsInZenMode: JCheckBox? = null
|
private var disableRainbowIndentsInZenMode: JCheckBox? = null
|
||||||
|
|
||||||
private var useColorGenerator: JCheckBox? = null
|
private var useColorGenerator: JCheckBox? = null
|
||||||
|
|
||||||
private var rainbowifyTagNameInXML: JCheckBox? = null
|
private var rainbowifyTagNameInXML: JCheckBox? = null
|
||||||
|
|
||||||
private var doNOTRainbowifyTemplateString: JCheckBox? = null
|
private var doNOTRainbowifyTemplateString: JCheckBox? = null
|
||||||
|
|
||||||
private var doNOTRainbowifyBigFiles: JCheckBox? = null
|
private var doNOTRainbowifyBigFiles: JCheckBox? = null
|
||||||
|
|
||||||
private var bigFilesLinesThreshold: JTextField? = null
|
private var bigFilesLinesThreshold: JTextField? = null
|
||||||
|
|
||||||
private var rainbowifyPythonKeywords: JCheckBox? = null
|
private var rainbowifyPythonKeywords: JCheckBox? = null
|
||||||
|
|
||||||
private val settings: RainbowSettings = RainbowSettings.instance
|
private val settings: RainbowSettings = RainbowSettings.instance
|
||||||
|
|
||||||
fun component(): JComponent? = panel
|
fun component(): JComponent? = panel
|
||||||
|
|
||||||
fun isRainbowEnabled() = enableRainbow?.isSelected
|
fun isRainbowEnabled() = enableRainbow?.isSelected
|
||||||
|
|
||||||
fun isRainbowRoundBracketsEnabled() = enableRainbowRoundBrackets?.isSelected
|
fun isRainbowRoundBracketsEnabled() = enableRainbowRoundBrackets?.isSelected
|
||||||
|
|
||||||
fun isRainbowSquigglyBracketsEnabled() = enableRainbowSquigglyBrackets?.isSelected
|
fun isRainbowSquigglyBracketsEnabled() = enableRainbowSquigglyBrackets?.isSelected
|
||||||
|
|
||||||
fun isRainbowSquareBracketsEnabled() = enableRainbowSquareBrackets?.isSelected
|
fun isRainbowSquareBracketsEnabled() = enableRainbowSquareBrackets?.isSelected
|
||||||
|
|
||||||
fun isRainbowAngleBracketsEnabled() = enableRainbowAngleBrackets?.isSelected
|
fun isRainbowAngleBracketsEnabled() = enableRainbowAngleBrackets?.isSelected
|
||||||
|
|
||||||
fun isShowRainbowIndentGuides() = showRainbowIndentGuides?.isSelected
|
fun isShowRainbowIndentGuides() = showRainbowIndentGuides?.isSelected
|
||||||
|
|
||||||
fun isDoNOTRainbowifyBracketsWithoutContent() = doNOTRainbowifyBracketsWithoutContent?.isSelected
|
fun isDoNOTRainbowifyBracketsWithoutContent() = doNOTRainbowifyBracketsWithoutContent?.isSelected
|
||||||
|
|
||||||
fun isDoNOTRainbowifyTheFirstLevel() = isDoNOTRainbowifyTheFirstLevel?.isSelected
|
fun isDoNOTRainbowifyTheFirstLevel() = isDoNOTRainbowifyTheFirstLevel?.isSelected
|
||||||
|
|
||||||
fun pressAnyKeyToRemoveTheHighlightingEffects() = pressAnyKeyToRemoveTheHighlightingEffects?.isSelected
|
fun pressAnyKeyToRemoveTheHighlightingEffects() = pressAnyKeyToRemoveTheHighlightingEffects?.isSelected
|
||||||
|
|
||||||
fun applyColorsOfRoundForAllBrackets() = applyColorsOfRoundForAllBrackets?.isSelected
|
fun applyColorsOfRoundForAllBrackets() = applyColorsOfRoundForAllBrackets?.isSelected
|
||||||
|
|
||||||
fun cycleCountOnAllBrackets() = cycleCountOnAllBrackets?.isSelected
|
fun cycleCountOnAllBrackets() = cycleCountOnAllBrackets?.isSelected
|
||||||
|
|
||||||
fun numberOfColors() = numberOfColors?.text?.toIntOrNull()
|
fun numberOfColors() = numberOfColors?.text?.toIntOrNull()
|
||||||
|
|
||||||
fun languageBlacklist() =
|
fun languageBlacklist() =
|
||||||
languageBlacklist?.text?.split(",")?.map { it.trim() }?.filterNot { it.isEmpty() }?.toSet()
|
languageBlacklist?.text?.split(",")?.map { it.trim() }?.filterNot { it.isEmpty() }?.toSet()
|
||||||
|
|
||||||
fun disableRainbowIndentsInZenMode() = disableRainbowIndentsInZenMode?.isSelected
|
fun disableRainbowIndentsInZenMode() = disableRainbowIndentsInZenMode?.isSelected
|
||||||
|
|
||||||
fun useColorGenerator() = useColorGenerator?.isSelected
|
fun useColorGenerator() = useColorGenerator?.isSelected
|
||||||
|
|
||||||
fun rainbowifyTagNameInXML() = rainbowifyTagNameInXML?.isSelected
|
fun rainbowifyTagNameInXML() = rainbowifyTagNameInXML?.isSelected
|
||||||
|
|
||||||
fun doNOTRainbowifyTemplateString() = doNOTRainbowifyTemplateString?.isSelected
|
fun doNOTRainbowifyTemplateString() = doNOTRainbowifyTemplateString?.isSelected
|
||||||
|
|
||||||
fun doNOTRainbowifyBigFiles() = doNOTRainbowifyBigFiles?.isSelected
|
fun doNOTRainbowifyBigFiles() = doNOTRainbowifyBigFiles?.isSelected
|
||||||
|
|
||||||
fun bigFilesLinesThreshold() = bigFilesLinesThreshold?.text?.toIntOrNull()
|
fun bigFilesLinesThreshold() = bigFilesLinesThreshold?.text?.toIntOrNull()
|
||||||
|
|
||||||
fun rainbowifyPythonKeywords() = rainbowifyPythonKeywords?.isSelected
|
fun rainbowifyPythonKeywords() = rainbowifyPythonKeywords?.isSelected
|
||||||
|
|
||||||
val isModified: Boolean
|
val isModified: Boolean
|
||||||
get() = (isRainbowEnabled() != settings.isRainbowEnabled
|
get() = (isRainbowEnabled() != settings.isRainbowEnabled
|
||||||
|| isRainbowAngleBracketsEnabled() != settings.isEnableRainbowAngleBrackets
|
|| isRainbowAngleBracketsEnabled() != settings.isEnableRainbowAngleBrackets
|
||||||
|| isRainbowRoundBracketsEnabled() != settings.isEnableRainbowRoundBrackets
|
|| isRainbowRoundBracketsEnabled() != settings.isEnableRainbowRoundBrackets
|
||||||
|| isRainbowSquigglyBracketsEnabled() != settings.isEnableRainbowSquigglyBrackets
|
|| isRainbowSquigglyBracketsEnabled() != settings.isEnableRainbowSquigglyBrackets
|
||||||
|| isRainbowSquareBracketsEnabled() != settings.isEnableRainbowSquareBrackets
|
|| isRainbowSquareBracketsEnabled() != settings.isEnableRainbowSquareBrackets
|
||||||
|| isShowRainbowIndentGuides() != settings.isShowRainbowIndentGuides
|
|| isShowRainbowIndentGuides() != settings.isShowRainbowIndentGuides
|
||||||
|| isDoNOTRainbowifyBracketsWithoutContent() != settings.isDoNOTRainbowifyBracketsWithoutContent
|
|| isDoNOTRainbowifyBracketsWithoutContent() != settings.isDoNOTRainbowifyBracketsWithoutContent
|
||||||
|| isDoNOTRainbowifyTheFirstLevel() != settings.isDoNOTRainbowifyTheFirstLevel
|
|| isDoNOTRainbowifyTheFirstLevel() != settings.isDoNOTRainbowifyTheFirstLevel
|
||||||
|| pressAnyKeyToRemoveTheHighlightingEffects() != settings.pressAnyKeyToRemoveTheHighlightingEffects
|
|| pressAnyKeyToRemoveTheHighlightingEffects() != settings.pressAnyKeyToRemoveTheHighlightingEffects
|
||||||
|| applyColorsOfRoundForAllBrackets() != settings.applyColorsOfRoundForAllBrackets
|
|| applyColorsOfRoundForAllBrackets() != settings.applyColorsOfRoundForAllBrackets
|
||||||
|| cycleCountOnAllBrackets() != settings.cycleCountOnAllBrackets
|
|| cycleCountOnAllBrackets() != settings.cycleCountOnAllBrackets
|
||||||
|| numberOfColors() != settings.numberOfColors
|
|| numberOfColors() != settings.numberOfColors
|
||||||
|| disableRainbowIndentsInZenMode() != settings.disableRainbowIndentsInZenMode
|
|| disableRainbowIndentsInZenMode() != settings.disableRainbowIndentsInZenMode
|
||||||
|| useColorGenerator() != settings.useColorGenerator
|
|| useColorGenerator() != settings.useColorGenerator
|
||||||
|| rainbowifyTagNameInXML() != settings.rainbowifyTagNameInXML
|
|| rainbowifyTagNameInXML() != settings.rainbowifyTagNameInXML
|
||||||
|| doNOTRainbowifyTemplateString() != settings.doNOTRainbowifyTemplateString
|
|| doNOTRainbowifyTemplateString() != settings.doNOTRainbowifyTemplateString
|
||||||
|| doNOTRainbowifyBigFiles() != settings.doNOTRainbowifyBigFiles
|
|| doNOTRainbowifyBigFiles() != settings.doNOTRainbowifyBigFiles
|
||||||
|| bigFilesLinesThreshold() != settings.bigFilesLinesThreshold
|
|| bigFilesLinesThreshold() != settings.bigFilesLinesThreshold
|
||||||
|| languageBlacklist() != settings.languageBlacklist
|
|| languageBlacklist() != settings.languageBlacklist
|
||||||
|| rainbowifyPythonKeywords() != settings.rainbowifyPythonKeywords
|
|| rainbowifyPythonKeywords() != settings.rainbowifyPythonKeywords
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
loadSettings()
|
loadSettings()
|
||||||
doNOTRainbowifyBigFiles?.addActionListener({e -> bigFilesLinesThreshold?.setEnabled(doNOTRainbowifyBigFiles() ?: false)})
|
doNOTRainbowifyBigFiles?.addActionListener { _ -> bigFilesLinesThreshold?.setEnabled(doNOTRainbowifyBigFiles() ?: false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadSettings() {
|
fun loadSettings() {
|
||||||
enableRainbow?.isSelected = settings.isRainbowEnabled
|
enableRainbow?.isSelected = settings.isRainbowEnabled
|
||||||
enableRainbowRoundBrackets?.isSelected = settings.isEnableRainbowRoundBrackets
|
enableRainbowRoundBrackets?.isSelected = settings.isEnableRainbowRoundBrackets
|
||||||
enableRainbowAngleBrackets?.isSelected = settings.isEnableRainbowAngleBrackets
|
enableRainbowAngleBrackets?.isSelected = settings.isEnableRainbowAngleBrackets
|
||||||
enableRainbowSquigglyBrackets?.isSelected = settings.isEnableRainbowSquigglyBrackets
|
enableRainbowSquigglyBrackets?.isSelected = settings.isEnableRainbowSquigglyBrackets
|
||||||
enableRainbowSquareBrackets?.isSelected = settings.isEnableRainbowSquareBrackets
|
enableRainbowSquareBrackets?.isSelected = settings.isEnableRainbowSquareBrackets
|
||||||
showRainbowIndentGuides?.isSelected = settings.isShowRainbowIndentGuides
|
showRainbowIndentGuides?.isSelected = settings.isShowRainbowIndentGuides
|
||||||
doNOTRainbowifyBracketsWithoutContent?.isSelected = settings.isDoNOTRainbowifyBracketsWithoutContent
|
doNOTRainbowifyBracketsWithoutContent?.isSelected = settings.isDoNOTRainbowifyBracketsWithoutContent
|
||||||
isDoNOTRainbowifyTheFirstLevel?.isSelected = settings.isDoNOTRainbowifyTheFirstLevel
|
isDoNOTRainbowifyTheFirstLevel?.isSelected = settings.isDoNOTRainbowifyTheFirstLevel
|
||||||
pressAnyKeyToRemoveTheHighlightingEffects?.isSelected = settings.pressAnyKeyToRemoveTheHighlightingEffects
|
pressAnyKeyToRemoveTheHighlightingEffects?.isSelected = settings.pressAnyKeyToRemoveTheHighlightingEffects
|
||||||
applyColorsOfRoundForAllBrackets?.isSelected = settings.applyColorsOfRoundForAllBrackets
|
applyColorsOfRoundForAllBrackets?.isSelected = settings.applyColorsOfRoundForAllBrackets
|
||||||
cycleCountOnAllBrackets?.isSelected = settings.cycleCountOnAllBrackets
|
cycleCountOnAllBrackets?.isSelected = settings.cycleCountOnAllBrackets
|
||||||
numberOfColors?.text = settings.numberOfColors.toString()
|
numberOfColors?.text = settings.numberOfColors.toString()
|
||||||
disableRainbowIndentsInZenMode?.isSelected = settings.disableRainbowIndentsInZenMode
|
disableRainbowIndentsInZenMode?.isSelected = settings.disableRainbowIndentsInZenMode
|
||||||
useColorGenerator?.isSelected = settings.useColorGenerator
|
useColorGenerator?.isSelected = settings.useColorGenerator
|
||||||
rainbowifyTagNameInXML?.isSelected = settings.rainbowifyTagNameInXML
|
rainbowifyTagNameInXML?.isSelected = settings.rainbowifyTagNameInXML
|
||||||
doNOTRainbowifyTemplateString?.isSelected = settings.doNOTRainbowifyTemplateString
|
doNOTRainbowifyTemplateString?.isSelected = settings.doNOTRainbowifyTemplateString
|
||||||
doNOTRainbowifyBigFiles?.isSelected = settings.doNOTRainbowifyBigFiles
|
doNOTRainbowifyBigFiles?.isSelected = settings.doNOTRainbowifyBigFiles
|
||||||
bigFilesLinesThreshold?.text = settings.bigFilesLinesThreshold.toString()
|
bigFilesLinesThreshold?.text = settings.bigFilesLinesThreshold.toString()
|
||||||
languageBlacklist?.text = settings.languageBlacklist.joinToString(",")
|
languageBlacklist?.text = settings.languageBlacklist.joinToString(",")
|
||||||
rainbowifyPythonKeywords?.isSelected = settings.rainbowifyPythonKeywords
|
rainbowifyPythonKeywords?.isSelected = settings.rainbowifyPythonKeywords
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,246 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Patrick Scheibe
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package com.github.izhangzhihao.rainbow.brackets.util
|
|
||||||
|
|
||||||
import com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings
|
|
||||||
import com.github.izhangzhihao.rainbow.brackets.util.ErrorContext.Companion.fromThrowable
|
|
||||||
import com.intellij.AbstractBundle
|
|
||||||
import com.intellij.diagnostic.*
|
|
||||||
import com.intellij.ide.DataManager
|
|
||||||
import com.intellij.ide.plugins.PluginManagerCore
|
|
||||||
import com.intellij.ide.plugins.PluginUtil
|
|
||||||
import com.intellij.idea.IdeaLogger
|
|
||||||
import com.intellij.notification.NotificationGroupManager
|
|
||||||
import com.intellij.notification.NotificationListener
|
|
||||||
import com.intellij.notification.NotificationType
|
|
||||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
|
||||||
import com.intellij.openapi.application.ApplicationNamesInfo
|
|
||||||
import com.intellij.openapi.application.ex.ApplicationInfoEx
|
|
||||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl
|
|
||||||
import com.intellij.openapi.diagnostic.ErrorReportSubmitter
|
|
||||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
|
|
||||||
import com.intellij.openapi.diagnostic.SubmittedReportInfo
|
|
||||||
import com.intellij.openapi.diagnostic.SubmittedReportInfo.SubmissionStatus
|
|
||||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
|
||||||
import com.intellij.openapi.progress.ProgressIndicator
|
|
||||||
import com.intellij.openapi.progress.ProgressManager
|
|
||||||
import com.intellij.openapi.progress.Task
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.SystemInfo
|
|
||||||
import com.intellij.util.Consumer
|
|
||||||
import org.eclipse.egit.github.core.Issue
|
|
||||||
import org.eclipse.egit.github.core.Label
|
|
||||||
import org.eclipse.egit.github.core.RepositoryId
|
|
||||||
import org.eclipse.egit.github.core.client.GitHubClient
|
|
||||||
import org.eclipse.egit.github.core.service.IssueService
|
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import org.jetbrains.annotations.NotNull
|
|
||||||
import org.jetbrains.annotations.Nullable
|
|
||||||
import org.jetbrains.annotations.PropertyKey
|
|
||||||
import java.awt.Component
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
private object AnonymousFeedback {
|
|
||||||
private const val gitRepoUser = "izhangzhihao"
|
|
||||||
|
|
||||||
//private const val gitRepoUser = "intellij-rainbow-brackets"
|
|
||||||
private const val gitRepo = "intellij-rainbow-brackets"
|
|
||||||
|
|
||||||
//private const val gitRepo = "bug"
|
|
||||||
private const val issueLabel = "Auto generated"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a connection to GitHub. Checks if there is an issue that is a duplicate and based on this, creates either a
|
|
||||||
* new issue or comments on the duplicate (if the user provided additional information).
|
|
||||||
*
|
|
||||||
* @param environmentDetails Information collected by [getKeyValuePairs]
|
|
||||||
* @return The report info that is then used in [GitHubErrorReporter] to show the user a balloon with the link
|
|
||||||
* of the created issue.
|
|
||||||
*/
|
|
||||||
internal fun sendFeedback(environmentDetails: MutableMap<String, String>): SubmittedReportInfo {
|
|
||||||
try {
|
|
||||||
val gitAccessToken = something
|
|
||||||
val client = GitHubClient()
|
|
||||||
client.setOAuth2Token(gitAccessToken)
|
|
||||||
val repoID = RepositoryId(gitRepoUser, gitRepo)
|
|
||||||
val issueService = IssueService(client)
|
|
||||||
var newGibHubIssue = createNewGibHubIssue(environmentDetails)
|
|
||||||
val duplicate = findFirstDuplicate(newGibHubIssue.title, issueService, repoID)
|
|
||||||
var isNewIssue = true
|
|
||||||
if (duplicate != null) {
|
|
||||||
issueService.createComment(repoID, duplicate.number, newGibHubIssue.body)
|
|
||||||
newGibHubIssue = duplicate
|
|
||||||
isNewIssue = false
|
|
||||||
} else newGibHubIssue = issueService.createIssue(repoID, newGibHubIssue)
|
|
||||||
return SubmittedReportInfo(newGibHubIssue.htmlUrl, ErrorReportBundle.message(
|
|
||||||
if (isNewIssue) "git.issue.text" else "git.issue.duplicate.text", newGibHubIssue.htmlUrl, newGibHubIssue.number.toLong()),
|
|
||||||
if (isNewIssue) SubmissionStatus.NEW_ISSUE else SubmissionStatus.DUPLICATE)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
return SubmittedReportInfo(null,
|
|
||||||
ErrorReportBundle.message("report.error.connection.failure"),
|
|
||||||
SubmissionStatus.FAILED)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findFirstDuplicate(title: String, service: IssueService, repo: RepositoryId): Issue? {
|
|
||||||
val openIssue = hashMapOf(IssueService.FILTER_STATE to IssueService.STATE_OPEN)
|
|
||||||
val closedIssue = hashMapOf(IssueService.FILTER_STATE to IssueService.STATE_CLOSED)
|
|
||||||
return service.pageIssues(repo, openIssue).flatten().firstOrNull { it.title == title }
|
|
||||||
?: service.pageIssues(repo, closedIssue).flatten().firstOrNull { it.title == title }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createNewGibHubIssue(details: MutableMap<String, String>) = Issue().apply {
|
|
||||||
val errorMessage = details.remove("error.message")?.takeIf(String::isNotBlank) ?: "Unspecified error"
|
|
||||||
title = ErrorReportBundle.message("git.issue.title", errorMessage)
|
|
||||||
body = generateGitHubIssueBody(details)
|
|
||||||
labels = listOf(Label().apply { name = issueLabel })
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateGitHubIssueBody(details: MutableMap<String, String>): String {
|
|
||||||
val errorDescription = details.remove("error.description").orEmpty()
|
|
||||||
val stackTrace = details.remove("error.stacktrace")?.takeIf(String::isNotBlank) ?: "invalid stacktrace"
|
|
||||||
val result = StringBuilder()
|
|
||||||
if (errorDescription.isNotEmpty()) {
|
|
||||||
result.append(errorDescription)
|
|
||||||
result.append("\n\n----------------------\n\n")
|
|
||||||
}
|
|
||||||
for ((key, value) in details) {
|
|
||||||
result.append("- ")
|
|
||||||
result.append(key)
|
|
||||||
result.append(": ")
|
|
||||||
result.append(value)
|
|
||||||
result.append("\n")
|
|
||||||
}
|
|
||||||
result.append("- StackTrace:\n")
|
|
||||||
result.append(stackTrace)
|
|
||||||
return result.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//String(Base64.getEncoder().encode("".toByteArray()))
|
|
||||||
private const val st = "YjgwZGRiY2U2YTNlYTAzM2UyZGU" + "yNDcyNWEyZjE3MGQ2YThmMjc0MQ=="
|
|
||||||
|
|
||||||
private val something: String by lazy { String(Base64.getDecoder().decode(st)) }
|
|
||||||
|
|
||||||
class GitHubErrorReporter : ErrorReportSubmitter() {
|
|
||||||
override fun getReportActionText() = ErrorReportBundle.message("report.error.to.plugin.vendor")
|
|
||||||
|
|
||||||
override fun submit(events: Array<out IdeaLoggingEvent>?, info: @Nullable String?, parent: @NotNull Component, consumer: @NotNull Consumer<in SubmittedReportInfo>): Boolean {
|
|
||||||
return doSubmit(events!![0], parent, consumer, fromThrowable(events[0].throwable), info)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doSubmit(
|
|
||||||
event: IdeaLoggingEvent,
|
|
||||||
parent: Component,
|
|
||||||
callback: Consumer<in SubmittedReportInfo>,
|
|
||||||
errorContext: ErrorContext,
|
|
||||||
description: String?): Boolean {
|
|
||||||
val dataContext = DataManager.getInstance().getDataContext(parent)
|
|
||||||
description?.let { errorContext.description = description }
|
|
||||||
errorContext.message = event.message
|
|
||||||
event.throwable?.let { throwable ->
|
|
||||||
PluginUtil.getInstance().findPluginId(throwable)?.let { pluginId ->
|
|
||||||
PluginManagerCore.getPlugin(pluginId)?.let { ideaPluginDescriptor ->
|
|
||||||
if (!ideaPluginDescriptor.isBundled) {
|
|
||||||
errorContext.pluginName = ideaPluginDescriptor.name
|
|
||||||
errorContext.pluginVersion = ideaPluginDescriptor.version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(event.data as? LogMessage)?.let { errorContext.attachments = it.includedAttachments }
|
|
||||||
val project = CommonDataKeys.PROJECT.getData(dataContext)
|
|
||||||
val reportValues = getKeyValuePairs(
|
|
||||||
errorContext,
|
|
||||||
ApplicationInfoImpl.getShadowInstance() as ApplicationInfoImpl,
|
|
||||||
ApplicationNamesInfo.getInstance())
|
|
||||||
val notifyingCallback = CallbackWithNotification(callback, project)
|
|
||||||
val task = AnonymousFeedbackTask(project, ErrorReportBundle.message(
|
|
||||||
"report.error.progress.dialog.text"), true, reportValues, notifyingCallback)
|
|
||||||
if (project == null) task.run(EmptyProgressIndicator()) else ProgressManager.getInstance().run(task)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class CallbackWithNotification(
|
|
||||||
private val consumer: Consumer<in SubmittedReportInfo>,
|
|
||||||
private val project: Project?) : Consumer<SubmittedReportInfo> {
|
|
||||||
override fun consume(reportInfo: SubmittedReportInfo) {
|
|
||||||
consumer.consume(reportInfo)
|
|
||||||
val GROUP = NotificationGroupManager.getInstance().getNotificationGroup("Error Report")
|
|
||||||
if (reportInfo.status == SubmissionStatus.FAILED) GROUP.createNotification(DiagnosticBundle.message("error.report.title"),
|
|
||||||
reportInfo.linkText, NotificationType.ERROR).setImportant(false).notify(project)
|
|
||||||
else GROUP.createNotification(DiagnosticBundle.message("error.report.title"), reportInfo.linkText,
|
|
||||||
NotificationType.INFORMATION).setListener(NotificationListener.URL_OPENING_LISTENER).setImportant(false).notify(project)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Messages and strings used by the error reporter
|
|
||||||
*/
|
|
||||||
private object ErrorReportBundle {
|
|
||||||
@NonNls
|
|
||||||
private const val BUNDLE = "error-reporting.report-bundle"
|
|
||||||
private val bundle: ResourceBundle by lazy { ResourceBundle.getBundle(BUNDLE) }
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
internal fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) =
|
|
||||||
AbstractBundle.message(bundle, key, *params)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AnonymousFeedbackTask(
|
|
||||||
project: Project?, title: String, canBeCancelled: Boolean,
|
|
||||||
private val params: MutableMap<String, String>,
|
|
||||||
private val callback: Consumer<SubmittedReportInfo>) : Task.Backgroundable(project, title, canBeCancelled, DEAF) {
|
|
||||||
override fun run(indicator: ProgressIndicator) {
|
|
||||||
callback.consume(AnonymousFeedback.sendFeedback(params))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collects information about the running IDEA and the error
|
|
||||||
*/
|
|
||||||
private fun getKeyValuePairs(
|
|
||||||
errorContext: ErrorContext,
|
|
||||||
appInfo: ApplicationInfoEx,
|
|
||||||
namesInfo: ApplicationNamesInfo): MutableMap<String, String> {
|
|
||||||
|
|
||||||
val params = mutableMapOf(
|
|
||||||
"error.description" to errorContext.description,
|
|
||||||
"Plugin Name" to errorContext.pluginName,
|
|
||||||
"Plugin Version" to RainbowSettings.instance.version,
|
|
||||||
"OS Name" to SystemInfo.OS_NAME,
|
|
||||||
"OS Version" to SystemInfo.OS_VERSION,
|
|
||||||
"Java Version" to SystemInfo.JAVA_VERSION,
|
|
||||||
"App Name" to namesInfo.productName,
|
|
||||||
"App Full Name" to namesInfo.fullProductName,
|
|
||||||
"Is Snapshot" to java.lang.Boolean.toString(appInfo.build.isSnapshot),
|
|
||||||
"App Build" to appInfo.build.asString(),
|
|
||||||
"error.message" to errorContext.errorClass,
|
|
||||||
"error.stacktrace" to "\n```\n" + errorContext.stackTrace + "\n```\n")
|
|
||||||
for (attachment in errorContext.attachments) {
|
|
||||||
params["attachment.${attachment.name}"] = attachment.path
|
|
||||||
params["attachment.${attachment.name}.value"] = "\n```\n" + attachment.displayText + "\n```\n"
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
}
|
|
@ -4,11 +4,11 @@ import java.awt.Color
|
|||||||
|
|
||||||
|
|
||||||
fun Color.alphaBlend(background: Color, alpha: Float): Color {
|
fun Color.alphaBlend(background: Color, alpha: Float): Color {
|
||||||
require(alpha in 0.0..1.0) { "alpha(0.0 <= alpha <= 1.0): $alpha" }
|
require(alpha in 0.0..1.0) { "alpha(0.0 <= alpha <= 1.0): $alpha" }
|
||||||
|
|
||||||
val r = (1 - alpha) * background.red + alpha * red
|
val r = (1 - alpha) * background.red + alpha * red
|
||||||
val g = (1 - alpha) * background.green + alpha * green
|
val g = (1 - alpha) * background.green + alpha * green
|
||||||
val b = (1 - alpha) * background.blue + alpha * blue
|
val b = (1 - alpha) * background.blue + alpha * blue
|
||||||
|
|
||||||
return Color(r.toInt(), g.toInt(), b.toInt())
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,53 +3,53 @@ package com.github.izhangzhihao.rainbow.brackets.util
|
|||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
fun <A, R> ((A) -> R).memoize(): (A) -> R = object : (A) -> R {
|
fun <A, R> ((A) -> R).memoize(): (A) -> R = object : (A) -> R {
|
||||||
private val m = MemoizedHandler<((A) -> R), MemoizeKey1<A, R>, R>(this@memoize)
|
private val m = MemoizedHandler<((A) -> R), MemoizeKey1<A, R>, R>(this@memoize)
|
||||||
override fun invoke(a: A) = m(MemoizeKey1(a))
|
override fun invoke(a: A) = m(MemoizeKey1(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <A, B, R> ((A, B) -> R).memoize(): (A, B) -> R = object : (A, B) -> R {
|
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)
|
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))
|
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 {
|
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)
|
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))
|
override fun invoke(a: A, b: B, c: C) = m(MemoizeKey3(a, b, c))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private interface MemoizedCall<in F, out R> {
|
private interface MemoizedCall<in F, out R> {
|
||||||
operator fun invoke(f: F): R
|
operator fun invoke(f: F): R
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MemoizedHandler<F, in K : MemoizedCall<F, R>, out R>(val f: F) {
|
private class MemoizedHandler<F, in K : MemoizedCall<F, R>, out R>(val f: F) {
|
||||||
private val m = Platform.newConcurrentMap<K, R>()
|
private val m = Platform.newConcurrentMap<K, R>()
|
||||||
operator fun invoke(k: K): R = m[k] ?: run { m.putSafely(k, k(f)) }
|
operator fun invoke(k: K): R = m[k] ?: run { m.putSafely(k, k(f)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class MemoizeKey1<out A, R>(val a: A) : MemoizedCall<(A) -> R, R> {
|
private data class MemoizeKey1<out A, R>(val a: A) : MemoizedCall<(A) -> R, R> {
|
||||||
override fun invoke(f: (A) -> R) = f(a)
|
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> {
|
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)
|
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> {
|
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)
|
override fun invoke(f: (A, B, C) -> R) = f(a, b, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
object Platform {
|
object Platform {
|
||||||
|
|
||||||
interface ConcurrentMap<K, V> : MutableMap<K, V> {
|
interface ConcurrentMap<K, V> : MutableMap<K, V> {
|
||||||
fun putSafely(k: K, v: V): V
|
fun putSafely(k: K, v: V): V
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <K, V> newConcurrentMap(): ConcurrentMap<K, V> {
|
fun <K, V> newConcurrentMap(): ConcurrentMap<K, V> {
|
||||||
val map by lazy { ConcurrentHashMap<K, V>() }
|
val map by lazy { ConcurrentHashMap<K, V>() }
|
||||||
return object : ConcurrentMap<K, V>, MutableMap<K, V> by map {
|
return object : ConcurrentMap<K, V>, MutableMap<K, V> by map {
|
||||||
override fun putSafely(k: K, v: V): V =
|
override fun putSafely(k: K, v: V): V =
|
||||||
map.putIfAbsent(k, v) ?: v
|
map.putIfAbsent(k, v) ?: v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,21 +1,8 @@
|
|||||||
package com.github.izhangzhihao.rainbow.brackets.util
|
package com.github.izhangzhihao.rainbow.brackets.util
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiDirectory
|
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiManager
|
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.toPsiFile(project: Project): PsiFile? = PsiManager.getInstance(project).findFile(this)
|
||||||
|
|
||||||
fun VirtualFile.toPsiDirectory(project: Project): PsiDirectory? = PsiManager.getInstance(project).findDirectory(this)
|
|
@ -9,19 +9,21 @@ val PsiElement.startOffset: Int get() = textRange.startOffset
|
|||||||
val PsiElement.endOffset: Int get() = textRange.endOffset
|
val PsiElement.endOffset: Int get() = textRange.endOffset
|
||||||
|
|
||||||
tailrec fun PsiElement.findPrevSibling(condition: (PsiElement) -> Boolean): PsiElement? {
|
tailrec fun PsiElement.findPrevSibling(condition: (PsiElement) -> Boolean): PsiElement? {
|
||||||
val prevSibling = prevSibling ?: return null
|
val prevSibling = prevSibling ?: return null
|
||||||
return if (condition(prevSibling)) {
|
return if (condition(prevSibling)) {
|
||||||
prevSibling
|
prevSibling
|
||||||
} else {
|
}
|
||||||
prevSibling.findPrevSibling(condition)
|
else {
|
||||||
}
|
prevSibling.findPrevSibling(condition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tailrec fun PsiElement.findNextSibling(condition: (PsiElement) -> Boolean): PsiElement? {
|
tailrec fun PsiElement.findNextSibling(condition: (PsiElement) -> Boolean): PsiElement? {
|
||||||
val nextSibling = nextSibling ?: return null
|
val nextSibling = nextSibling ?: return null
|
||||||
return if (condition(nextSibling)) {
|
return if (condition(nextSibling)) {
|
||||||
nextSibling
|
nextSibling
|
||||||
} else {
|
}
|
||||||
nextSibling.findNextSibling(condition)
|
else {
|
||||||
}
|
nextSibling.findNextSibling(condition)
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ import com.intellij.openapi.editor.markup.TextAttributes
|
|||||||
import kotlin.reflect.jvm.isAccessible
|
import kotlin.reflect.jvm.isAccessible
|
||||||
|
|
||||||
fun create(name: String, textAttributes: TextAttributes): TextAttributesKey {
|
fun create(name: String, textAttributes: TextAttributes): TextAttributesKey {
|
||||||
val cons = TextAttributesKey::class.constructors.first { it.parameters.size == 3 }
|
val cons = TextAttributesKey::class.constructors.first { it.parameters.size == 3 }
|
||||||
cons.isAccessible = true
|
cons.isAccessible = true
|
||||||
return cons.call(name, textAttributes, null)
|
return cons.call(name, textAttributes, null)
|
||||||
}
|
}
|
@ -7,120 +7,128 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.GT
|
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LPARENTH
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LPARENTH
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.LT
|
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.RPARENTH
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.lexer.CSharpTokenType.RPARENTH
|
||||||
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.psi.CSharpDummyNode
|
import com.jetbrains.rider.ideaInterop.fileTypes.csharp.psi.CSharpDummyNode
|
||||||
|
|
||||||
|
|
||||||
class CSharpRainbowVisitor : RainbowHighlightVisitor() {
|
class CSharpRainbowVisitor : RainbowHighlightVisitor() {
|
||||||
|
|
||||||
override fun suitableForFile(file: PsiFile)
|
override fun suitableForFile(file: PsiFile)
|
||||||
: Boolean = super.suitableForFile(file) &&
|
: Boolean = super.suitableForFile(file) &&
|
||||||
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
||||||
(file.language.id == "C#" ||
|
(file.language.id == "C#" ||
|
||||||
file.viewProvider.allFiles.any { it.language.id == "C#" }
|
file.viewProvider.allFiles.any { it.language.id == "C#" }
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun clone(): HighlightVisitor = CSharpRainbowVisitor()
|
override fun clone(): HighlightVisitor = CSharpRainbowVisitor()
|
||||||
|
|
||||||
override fun visit(element: PsiElement) {
|
override fun visit(element: PsiElement) {
|
||||||
val type = (element as? LeafPsiElement)?.elementType ?: return
|
val type = (element as? LeafPsiElement)?.elementType ?: return
|
||||||
val pair = map[type]
|
val pair = map[type]
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
val level = element.getBracketLevel(pair, type)
|
val level = element.getBracketLevel(pair, type)
|
||||||
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
||||||
if (level >= 1) {
|
if (level >= 1) {
|
||||||
rainbowPairs(element, pair, level)
|
rainbowPairs(element, pair, level)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (level >= 0) {
|
else {
|
||||||
rainbowPairs(element, pair, level)
|
if (level >= 0) {
|
||||||
}
|
rainbowPairs(element, pair, level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
|
private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
|
||||||
val startElement = element.takeIf { it.elementType == pair.leftBraceType }
|
val startElement = element.takeIf { it.elementType == pair.leftBraceType }
|
||||||
val endElement = element.takeIf { it.elementType == pair.rightBraceType }
|
val endElement = element.takeIf { it.elementType == pair.rightBraceType }
|
||||||
element.setHighlightInfo(element.parent, level, startElement, endElement)
|
element.setHighlightInfo(element.parent, level, startElement, endElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val map = mapOf(
|
val map = mapOf(
|
||||||
LPARENTH to BracePair(LPARENTH, RPARENTH, true),
|
LPARENTH to BracePair(LPARENTH, RPARENTH, true),
|
||||||
RPARENTH to BracePair(LPARENTH, RPARENTH, true),
|
RPARENTH to BracePair(LPARENTH, RPARENTH, true),
|
||||||
//LT to BracePair(LT, GT, true),
|
//LT to BracePair(LT, GT, true),
|
||||||
//GT 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 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 {
|
private tailrec fun iterateBracketParents(element: PsiElement?, pair: BracePair, count: Int, type: IElementType): Int {
|
||||||
if (element == null || element is PsiFile) {
|
if (element == null || element is PsiFile) {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextCount = count
|
var nextCount = count
|
||||||
|
|
||||||
if (element is LeafPsiElement && type == pair.leftBraceType && element.elementType == pair.rightBraceType) {
|
if (element is LeafPsiElement && type == pair.leftBraceType && element.elementType == pair.rightBraceType) {
|
||||||
nextCount--
|
nextCount--
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element is LeafPsiElement && type == pair.rightBraceType && element.elementType == pair.leftBraceType) {
|
if (element is LeafPsiElement && type == pair.rightBraceType && element.elementType == pair.leftBraceType) {
|
||||||
nextCount--
|
nextCount--
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element is LeafPsiElement && element.elementType == type) {
|
if (element is LeafPsiElement && element.elementType == type) {
|
||||||
nextCount++
|
nextCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (type == pair.leftBraceType) {
|
return if (type == pair.leftBraceType) {
|
||||||
val prev = element.prevSibling
|
val prev = element.prevSibling
|
||||||
if (prev == null) {
|
if (prev == null) {
|
||||||
iterateBracketParents(element.parent.prevSibling.iterForPreDummyNode()?.lastChild, pair, nextCount, type)
|
iterateBracketParents(element.parent.prevSibling.iterForPreDummyNode()?.lastChild, pair, nextCount, type)
|
||||||
} else {
|
}
|
||||||
iterateBracketParents(prev, pair, nextCount, type)
|
else {
|
||||||
}
|
iterateBracketParents(prev, pair, nextCount, type)
|
||||||
} else {
|
}
|
||||||
val next = element.nextSibling
|
}
|
||||||
if (next == null) {
|
else {
|
||||||
iterateBracketParents(element.parent.nextSibling.iterForNextDummyNode()?.firstChild, pair, nextCount, type)
|
val next = element.nextSibling
|
||||||
} else {
|
if (next == null) {
|
||||||
iterateBracketParents(next, pair, nextCount, type)
|
iterateBracketParents(element.parent.nextSibling.iterForNextDummyNode()?.firstChild, pair, nextCount, type)
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
iterateBracketParents(next, pair, nextCount, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private tailrec fun PsiElement?.iterForNextDummyNode(): PsiElement? {
|
private tailrec fun PsiElement?.iterForNextDummyNode(): PsiElement? {
|
||||||
return if (this == null) {
|
return if (this == null) {
|
||||||
null
|
null
|
||||||
} else if (this is CSharpDummyNode) {
|
}
|
||||||
this
|
else if (this is CSharpDummyNode) {
|
||||||
} else {
|
this
|
||||||
if (this.nextSibling == null) {
|
}
|
||||||
null
|
else {
|
||||||
} else {
|
if (this.nextSibling == null) {
|
||||||
this.nextSibling.iterForNextDummyNode()
|
null
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
this.nextSibling.iterForNextDummyNode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private tailrec fun PsiElement?.iterForPreDummyNode(): PsiElement? {
|
private tailrec fun PsiElement?.iterForPreDummyNode(): PsiElement? {
|
||||||
return if (this == null) {
|
return if (this == null) {
|
||||||
null
|
null
|
||||||
} else if (this is CSharpDummyNode) {
|
}
|
||||||
this
|
else if (this is CSharpDummyNode) {
|
||||||
} else {
|
this
|
||||||
if (this.prevSibling == null) {
|
}
|
||||||
null
|
else {
|
||||||
} else {
|
if (this.prevSibling == null) {
|
||||||
this.prevSibling.iterForPreDummyNode()
|
null
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
this.prevSibling.iterForPreDummyNode()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -13,159 +13,169 @@ import com.intellij.psi.tree.IElementType
|
|||||||
|
|
||||||
class DefaultRainbowVisitor : RainbowHighlightVisitor() {
|
class DefaultRainbowVisitor : RainbowHighlightVisitor() {
|
||||||
|
|
||||||
override fun clone(): HighlightVisitor = DefaultRainbowVisitor()
|
override fun clone(): HighlightVisitor = DefaultRainbowVisitor()
|
||||||
|
|
||||||
override fun visit(element: PsiElement) {
|
override fun visit(element: PsiElement) {
|
||||||
val type = (element as? LeafPsiElement)?.elementType ?: return
|
val type = (element as? LeafPsiElement)?.elementType ?: return
|
||||||
val matching = filterPairs(type, element) ?: return
|
val matching = filterPairs(type, element) ?: return
|
||||||
|
|
||||||
val pair =
|
val pair =
|
||||||
if (matching.size == 1) {
|
if (matching.size == 1) {
|
||||||
matching[0]
|
matching[0]
|
||||||
} else {
|
}
|
||||||
matching.find { element.isValidBracket(it) }
|
else {
|
||||||
} ?: return
|
matching.find { element.isValidBracket(it) }
|
||||||
|
} ?: return
|
||||||
|
|
||||||
val level = element.getBracketLevel(pair)
|
val level = element.getBracketLevel(pair)
|
||||||
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
||||||
if (level >= 1) {
|
if (level >= 1) {
|
||||||
rainbowPairs(element, pair, level)
|
rainbowPairs(element, pair, level)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (level >= 0) {
|
else {
|
||||||
rainbowPairs(element, pair, level)
|
if (level >= 0) {
|
||||||
}
|
rainbowPairs(element, pair, level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
|
private fun rainbowPairs(element: LeafPsiElement, pair: BracePair, level: Int) {
|
||||||
val startElement = element.takeIf { it.elementType == pair.leftBraceType }
|
val startElement = element.takeIf { it.elementType == pair.leftBraceType }
|
||||||
val endElement = element.takeIf { it.elementType == pair.rightBraceType }
|
val endElement = element.takeIf { it.elementType == pair.rightBraceType }
|
||||||
element.setHighlightInfo(element.parent, level, startElement, endElement)
|
element.setHighlightInfo(element.parent, level, startElement, endElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private fun LeafPsiElement.getBracketLevel(pair: BracePair): Int = iterateBracketParents(parent, pair, -1)
|
private fun LeafPsiElement.getBracketLevel(pair: BracePair): Int = iterateBracketParents(parent, pair, -1)
|
||||||
|
|
||||||
private tailrec fun iterateBracketParents(element: PsiElement?, pair: BracePair, count: Int): Int {
|
private tailrec fun iterateBracketParents(element: PsiElement?, pair: BracePair, count: Int): Int {
|
||||||
if (element == null || element is PsiFile) {
|
if (element == null || element is PsiFile) {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextCount = count
|
var nextCount = count
|
||||||
if (!RainbowSettings.instance.cycleCountOnAllBrackets) {
|
if (!RainbowSettings.instance.cycleCountOnAllBrackets) {
|
||||||
if (element.haveBrackets({ it.elementType() == pair.leftBraceType },
|
if (element.haveBrackets(
|
||||||
{ it.elementType() == pair.rightBraceType })
|
{ it.elementType() == pair.leftBraceType },
|
||||||
) {
|
{ it.elementType() == pair.rightBraceType })
|
||||||
nextCount++
|
) {
|
||||||
}
|
nextCount++
|
||||||
} else {
|
}
|
||||||
if (element.haveBrackets({ element.language.braceTypeSet.contains(it.elementType()) },
|
}
|
||||||
{ element.language.braceTypeSet.contains(it.elementType()) })
|
else {
|
||||||
) {
|
if (element.haveBrackets(
|
||||||
nextCount++
|
{ element.language.braceTypeSet.contains(it.elementType()) },
|
||||||
}
|
{ element.language.braceTypeSet.contains(it.elementType()) })
|
||||||
}
|
) {
|
||||||
|
nextCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return iterateBracketParents(element.parent, pair, nextCount)
|
return iterateBracketParents(element.parent, pair, nextCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun PsiElement.haveBrackets(
|
private inline fun PsiElement.haveBrackets(
|
||||||
checkLeft: (PsiElement) -> Boolean,
|
checkLeft: (PsiElement) -> Boolean,
|
||||||
checkRight: (PsiElement) -> Boolean
|
checkRight: (PsiElement) -> Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (this is LeafPsiElement) {
|
if (this is LeafPsiElement) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var findLeftBracket = false
|
var findLeftBracket = false
|
||||||
var findRightBracket = false
|
var findRightBracket = false
|
||||||
var left: PsiElement? = firstChild
|
var left: PsiElement? = firstChild
|
||||||
var right: PsiElement? = lastChild
|
var right: PsiElement? = lastChild
|
||||||
while (left != right && (!findLeftBracket || !findRightBracket)) {
|
while (left != right && (!findLeftBracket || !findRightBracket)) {
|
||||||
val needBreak = left == null || left.nextSibling == right
|
val needBreak = left == null || left.nextSibling == right
|
||||||
|
|
||||||
if (left is LeafPsiElement && checkLeft(left)) {
|
if (left is LeafPsiElement && checkLeft(left)) {
|
||||||
findLeftBracket = true
|
findLeftBracket = true
|
||||||
} else {
|
}
|
||||||
left = left?.nextSibling
|
else {
|
||||||
}
|
left = left?.nextSibling
|
||||||
if (right is LeafPsiElement && checkRight(right)) {
|
}
|
||||||
findRightBracket = true
|
if (right is LeafPsiElement && checkRight(right)) {
|
||||||
} else {
|
findRightBracket = true
|
||||||
right = right?.prevSibling
|
}
|
||||||
}
|
else {
|
||||||
|
right = right?.prevSibling
|
||||||
|
}
|
||||||
|
|
||||||
if (needBreak) {
|
if (needBreak) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//For https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/830
|
//For https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/830
|
||||||
if (RainbowSettings.instance.doNOTRainbowifyTemplateString) {
|
if (RainbowSettings.instance.doNOTRainbowifyTemplateString) {
|
||||||
if (left?.prevSibling?.textMatches("$") == true) return false
|
if (left?.prevSibling?.textMatches("$") == true) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return findLeftBracket && findRightBracket
|
return findLeftBracket && findRightBracket
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PsiElement.elementType(): IElementType? {
|
private fun PsiElement.elementType(): IElementType? {
|
||||||
return (this as? LeafPsiElement)?.elementType
|
return (this as? LeafPsiElement)?.elementType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LeafPsiElement.isValidBracket(pair: BracePair): Boolean {
|
private fun LeafPsiElement.isValidBracket(pair: BracePair): Boolean {
|
||||||
val pairType = when (elementType) {
|
val pairType = when (elementType) {
|
||||||
pair.leftBraceType -> pair.rightBraceType
|
pair.leftBraceType -> pair.rightBraceType
|
||||||
pair.rightBraceType -> pair.leftBraceType
|
pair.rightBraceType -> pair.leftBraceType
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (pairType == pair.leftBraceType) {
|
return if (pairType == pair.leftBraceType) {
|
||||||
checkBracePair(this, parent.firstChild, pairType, PsiElement::getNextSibling)
|
checkBracePair(this, parent.firstChild, pairType, PsiElement::getNextSibling)
|
||||||
} else {
|
}
|
||||||
checkBracePair(this, parent.lastChild, pairType, PsiElement::getPrevSibling)
|
else {
|
||||||
}
|
checkBracePair(this, parent.lastChild, pairType, PsiElement::getPrevSibling)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkBracePair(
|
private fun checkBracePair(
|
||||||
brace: PsiElement,
|
brace: PsiElement,
|
||||||
start: PsiElement,
|
start: PsiElement,
|
||||||
type: IElementType,
|
type: IElementType,
|
||||||
next: PsiElement.() -> PsiElement?
|
next: PsiElement.() -> PsiElement?,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
var element: PsiElement? = start
|
var element: PsiElement? = start
|
||||||
while (element != null && element != brace) {
|
while (element != null && element != brace) {
|
||||||
if (element is LeafPsiElement && element.elementType == type) {
|
if (element is LeafPsiElement && element.elementType == type) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
element = element.next()
|
element = element.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filterPairs(type: IElementType, element: LeafPsiElement): List<BracePair>? {
|
private fun filterPairs(type: IElementType, element: LeafPsiElement): List<BracePair>? {
|
||||||
val pairs = element.language.bracePairs ?: return null
|
val pairs = element.language.bracePairs ?: return null
|
||||||
val filterBraceType = pairs[type.toString()]
|
val filterBraceType = pairs[type.toString()]
|
||||||
return when {
|
return when {
|
||||||
filterBraceType == null || filterBraceType.isEmpty() -> {
|
filterBraceType.isNullOrEmpty() -> {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/198
|
// https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/198
|
||||||
element.javaClass.simpleName == "OCMacroForeignLeafElement" -> {
|
element.javaClass.simpleName == "OCMacroForeignLeafElement" -> {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
RainbowSettings.instance.isDoNOTRainbowifyBracketsWithoutContent -> {
|
|
||||||
filterBraceType
|
RainbowSettings.instance.isDoNOTRainbowifyBracketsWithoutContent -> {
|
||||||
.filterNot { it.leftBraceType == type && element.nextSibling?.elementType() == it.rightBraceType }
|
filterBraceType
|
||||||
.filterNot { it.rightBraceType == type && element.prevSibling?.elementType() == it.leftBraceType }
|
.filterNot { it.leftBraceType == type && element.nextSibling?.elementType() == it.rightBraceType }
|
||||||
}
|
.filterNot { it.rightBraceType == type && element.prevSibling?.elementType() == it.leftBraceType }
|
||||||
else -> {
|
}
|
||||||
filterBraceType
|
|
||||||
}
|
else -> {
|
||||||
}
|
filterBraceType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,31 +13,31 @@ import com.intellij.psi.xml.XmlTokenType
|
|||||||
|
|
||||||
class PugRainbowVisitor : RainbowHighlightVisitor() {
|
class PugRainbowVisitor : RainbowHighlightVisitor() {
|
||||||
|
|
||||||
override fun suitableForFile(file: PsiFile)
|
override fun suitableForFile(file: PsiFile)
|
||||||
: Boolean = super.suitableForFile(file) &&
|
: Boolean = super.suitableForFile(file) &&
|
||||||
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
||||||
(file.language.id == "Jade" ||
|
(file.language.id == "Jade" ||
|
||||||
file.viewProvider.allFiles.any { it.language.id == "Jade" } ||
|
file.viewProvider.allFiles.any { it.language.id == "Jade" } ||
|
||||||
file.name.endsWith(".vue")
|
file.name.endsWith(".vue")
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun clone(): HighlightVisitor = PugRainbowVisitor()
|
override fun clone(): HighlightVisitor = PugRainbowVisitor()
|
||||||
|
|
||||||
override fun visit(element: PsiElement) {
|
override fun visit(element: PsiElement) {
|
||||||
if (element !is XmlToken) {
|
if (element !is XmlToken) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.tokenType == XmlTokenType.XML_TAG_NAME) {
|
if (element.tokenType == XmlTokenType.XML_TAG_NAME) {
|
||||||
val parent = element.parent
|
val parent = element.parent
|
||||||
if (parent != null && parent is XmlTag) {
|
if (parent != null && parent is XmlTag) {
|
||||||
parent.level.let { element.setHighlightInfo(element.xmlParent, it, element, null) }
|
parent.level.let { element.setHighlightInfo(element.xmlParent, it, element, null) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val XmlTag.level: Int
|
private val XmlTag.level: Int
|
||||||
get() = iterateXmlTagParents(parent, 0)
|
get() = iterateXmlTagParents(parent, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,83 +5,99 @@ import com.intellij.codeInsight.daemon.impl.HighlightVisitor
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
import com.jetbrains.python.PyTokenTypes.*
|
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
|
import com.jetbrains.python.psi.PyStatement
|
||||||
|
|
||||||
|
|
||||||
class PythonRainbowVisitor : RainbowHighlightVisitor() {
|
class PythonRainbowVisitor : RainbowHighlightVisitor() {
|
||||||
|
|
||||||
override fun suitableForFile(file: PsiFile)
|
override fun suitableForFile(file: PsiFile)
|
||||||
: Boolean = super.suitableForFile(file) &&
|
: Boolean = super.suitableForFile(file) &&
|
||||||
RainbowSettings.instance.rainbowifyPythonKeywords &&
|
RainbowSettings.instance.rainbowifyPythonKeywords &&
|
||||||
(file.language.id == "Python" ||
|
(file.language.id == "Python" ||
|
||||||
file.viewProvider.allFiles.any { it.language.id == "Python" }
|
file.viewProvider.allFiles.any { it.language.id == "Python" }
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun clone(): HighlightVisitor = PythonRainbowVisitor()
|
override fun clone(): HighlightVisitor = PythonRainbowVisitor()
|
||||||
|
|
||||||
override fun visit(element: PsiElement) {
|
override fun visit(element: PsiElement) {
|
||||||
val type = (element as? LeafPsiElement)?.elementType ?: return
|
val type = (element as? LeafPsiElement)?.elementType ?: return
|
||||||
val exists = statementKeywords.contains(type)
|
val exists = statementKeywords.contains(type)
|
||||||
if (exists) {
|
if (exists) {
|
||||||
val level = element.getBracketLevel()
|
val level = element.getBracketLevel()
|
||||||
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
if (RainbowSettings.instance.isDoNOTRainbowifyTheFirstLevel) {
|
||||||
if (level >= 1) {
|
if (level >= 1) {
|
||||||
rainbowPairs(element, level)
|
rainbowPairs(element, level)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (level >= 0) {
|
else {
|
||||||
rainbowPairs(element, level)
|
if (level >= 0) {
|
||||||
}
|
rainbowPairs(element, level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun rainbowPairs(element: LeafPsiElement, level: Int) {
|
private fun rainbowPairs(element: LeafPsiElement, level: Int) {
|
||||||
element.setHighlightInfo(element.parent, level, element, element)
|
element.setHighlightInfo(element.parent, level, element, element)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val statementKeywords = setOf(
|
val statementKeywords = setOf(
|
||||||
IF_KEYWORD,
|
IF_KEYWORD,
|
||||||
ELSE_KEYWORD,
|
ELSE_KEYWORD,
|
||||||
ELIF_KEYWORD,
|
ELIF_KEYWORD,
|
||||||
BREAK_KEYWORD,
|
BREAK_KEYWORD,
|
||||||
CONTINUE_KEYWORD,
|
CONTINUE_KEYWORD,
|
||||||
CLASS_KEYWORD,
|
CLASS_KEYWORD,
|
||||||
DEF_KEYWORD,
|
DEF_KEYWORD,
|
||||||
EXCEPT_KEYWORD,
|
EXCEPT_KEYWORD,
|
||||||
FINALLY_KEYWORD,
|
FINALLY_KEYWORD,
|
||||||
FOR_KEYWORD,
|
FOR_KEYWORD,
|
||||||
RAISE_KEYWORD,
|
RAISE_KEYWORD,
|
||||||
RETURN_KEYWORD,
|
RETURN_KEYWORD,
|
||||||
TRY_KEYWORD,
|
TRY_KEYWORD,
|
||||||
WITH_KEYWORD,
|
WITH_KEYWORD,
|
||||||
WHILE_KEYWORD,
|
WHILE_KEYWORD,
|
||||||
YIELD_KEYWORD,
|
YIELD_KEYWORD,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun LeafPsiElement.getBracketLevel(): Int =
|
private fun LeafPsiElement.getBracketLevel(): Int =
|
||||||
iterateBracketParents(this, -1)
|
iterateBracketParents(this, -1)
|
||||||
|
|
||||||
private tailrec fun iterateBracketParents(
|
private tailrec fun iterateBracketParents(
|
||||||
element: PsiElement?,
|
element: PsiElement?,
|
||||||
count: Int
|
count: Int,
|
||||||
): Int {
|
): Int {
|
||||||
if (element == null || element is PsiFile) {
|
if (element == null || element is PsiFile) {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextCount = count
|
var nextCount = count
|
||||||
|
|
||||||
if (element is PyStatement) {
|
if (element is PyStatement) {
|
||||||
nextCount++
|
nextCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
return iterateBracketParents(
|
return iterateBracketParents(
|
||||||
element.parent,
|
element.parent,
|
||||||
nextCount,
|
nextCount,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,96 +19,101 @@ import java.awt.Color
|
|||||||
|
|
||||||
abstract class RainbowHighlightVisitor : HighlightVisitor {
|
abstract class RainbowHighlightVisitor : HighlightVisitor {
|
||||||
|
|
||||||
private var highlightInfoHolder: HighlightInfoHolder? = null
|
private var highlightInfoHolder: HighlightInfoHolder? = null
|
||||||
|
|
||||||
override fun suitableForFile(file: PsiFile): Boolean {
|
override fun suitableForFile(file: PsiFile): Boolean {
|
||||||
return RainbowSettings.instance.isRainbowEnabled &&
|
return RainbowSettings.instance.isRainbowEnabled &&
|
||||||
checkForBigFile(file) &&
|
checkForBigFile(file) &&
|
||||||
!RainbowSettings.instance.languageBlacklist.contains(file.fileType.name) &&
|
!RainbowSettings.instance.languageBlacklist.contains(file.fileType.name) &&
|
||||||
!RainbowSettings.instance.languageBlacklist.contains(memoizedFileExtension(file.name)) &&
|
!RainbowSettings.instance.languageBlacklist.contains(memoizedFileExtension(file.name)) &&
|
||||||
fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(file.fileType.name)
|
fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(file.fileType.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun analyze(file: PsiFile, updateWholeFile: Boolean, holder: HighlightInfoHolder, action: Runnable): Boolean {
|
final override fun analyze(file: PsiFile, updateWholeFile: Boolean, holder: HighlightInfoHolder, action: Runnable): Boolean {
|
||||||
highlightInfoHolder = holder
|
highlightInfoHolder = holder
|
||||||
onBeforeAnalyze(file, updateWholeFile)
|
onBeforeAnalyze(file, updateWholeFile)
|
||||||
try {
|
try {
|
||||||
action.run()
|
action.run()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
} finally {
|
} finally {
|
||||||
onAfterAnalyze()
|
onAfterAnalyze()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun onBeforeAnalyze(file: PsiFile, updateWholeFile: Boolean) = Unit
|
protected open fun onBeforeAnalyze(file: PsiFile, updateWholeFile: Boolean) = Unit
|
||||||
|
|
||||||
protected open fun onAfterAnalyze() {
|
protected open fun onAfterAnalyze() {
|
||||||
highlightInfoHolder = null
|
highlightInfoHolder = null
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun PsiElement.setHighlightInfo(parent: PsiElement?,
|
protected fun PsiElement.setHighlightInfo(
|
||||||
level: Int,
|
parent: PsiElement?,
|
||||||
startElement: PsiElement?,
|
level: Int,
|
||||||
endElement: PsiElement?) {
|
startElement: PsiElement?,
|
||||||
val holder = highlightInfoHolder ?: return
|
endElement: PsiElement?,
|
||||||
val globalScheme = EditorColorsManager.getInstance().globalScheme
|
) {
|
||||||
getHighlightInfo(globalScheme, this, level)
|
val holder = highlightInfoHolder ?: return
|
||||||
?.also {
|
val globalScheme = EditorColorsManager.getInstance().globalScheme
|
||||||
holder.add(it)
|
getHighlightInfo(globalScheme, this, level)
|
||||||
|
?.also {
|
||||||
|
holder.add(it)
|
||||||
|
|
||||||
if (startElement != null || endElement != null) {
|
if (startElement != null || endElement != null) {
|
||||||
val color: Color? = globalScheme.getAttributes(it.forcedTextAttributesKey)?.foregroundColor
|
val color: Color? = globalScheme.getAttributes(it.forcedTextAttributesKey)?.foregroundColor
|
||||||
color?.let {
|
color?.let {
|
||||||
parent?.saveRainbowInfo(level, color, startElement, endElement)
|
parent?.saveRainbowInfo(level, color, startElement, endElement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PsiElement.saveRainbowInfo(level: Int,
|
private fun PsiElement.saveRainbowInfo(
|
||||||
color: Color,
|
level: Int,
|
||||||
startElement: PsiElement?,
|
color: Color,
|
||||||
endElement: PsiElement?) {
|
startElement: PsiElement?,
|
||||||
val rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[this]?.also {
|
endElement: PsiElement?,
|
||||||
it.level = level
|
) {
|
||||||
it.color = color
|
val rainbowInfo = RainbowInfo.RAINBOW_INFO_KEY[this]?.also {
|
||||||
} ?: RainbowInfo(level, color).also { RainbowInfo.RAINBOW_INFO_KEY[this] = it }
|
it.level = level
|
||||||
|
it.color = color
|
||||||
|
} ?: RainbowInfo(level, color).also { RainbowInfo.RAINBOW_INFO_KEY[this] = it }
|
||||||
|
|
||||||
startElement?.let { rainbowInfo.startElement = it }
|
startElement?.let { rainbowInfo.startElement = it }
|
||||||
endElement?.let { rainbowInfo.endElement = it }
|
endElement?.let { rainbowInfo.endElement = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val isIntelliJHaskellEnabled: Boolean by lazy {
|
private val isIntelliJHaskellEnabled: Boolean by lazy {
|
||||||
PluginManagerCore.getPlugin(
|
PluginManagerCore.getPlugin(
|
||||||
PluginId.getId("intellij.haskell"))?.isEnabled ?: false
|
PluginId.getId("intellij.haskell")
|
||||||
}
|
)?.isEnabled ?: false
|
||||||
|
}
|
||||||
|
|
||||||
fun checkForBigFile(file: PsiFile): Boolean =
|
fun checkForBigFile(file: PsiFile): Boolean =
|
||||||
!(RainbowSettings.instance.doNOTRainbowifyBigFiles &&
|
!(RainbowSettings.instance.doNOTRainbowifyBigFiles &&
|
||||||
file.getLineCount() > RainbowSettings.instance.bigFilesLinesThreshold)
|
file.getLineCount() > RainbowSettings.instance.bigFilesLinesThreshold)
|
||||||
|
|
||||||
private fun fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(fileType: String) =
|
private fun fileIsNotHaskellOrIntelliJHaskellPluginNotEnabled(fileType: String) =
|
||||||
fileType != "Haskell" || !isIntelliJHaskellEnabled
|
fileType != "Haskell" || !isIntelliJHaskellEnabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiElement.getLineCount(): Int {
|
fun PsiElement.getLineCount(): Int {
|
||||||
try {
|
try {
|
||||||
val doc = containingFile?.let { PsiDocumentManager.getInstance(project).getDocument(it) }
|
val doc = containingFile?.let { PsiDocumentManager.getInstance(project).getDocument(it) }
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
val spaceRange = textRange ?: TextRange.EMPTY_RANGE
|
val spaceRange = textRange ?: TextRange.EMPTY_RANGE
|
||||||
|
|
||||||
if (spaceRange.endOffset <= doc.textLength && spaceRange.startOffset < spaceRange.endOffset) {
|
if (spaceRange.endOffset <= doc.textLength && spaceRange.startOffset < spaceRange.endOffset) {
|
||||||
val startLine = doc.getLineNumber(spaceRange.startOffset)
|
val startLine = doc.getLineNumber(spaceRange.startOffset)
|
||||||
val endLine = doc.getLineNumber(spaceRange.endOffset - 1)
|
val endLine = doc.getLineNumber(spaceRange.endOffset - 1)
|
||||||
|
|
||||||
return endLine - startLine + 1
|
return endLine - startLine + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return StringUtil.getLineBreakCount(text ?: "") + 1
|
return StringUtil.getLineBreakCount(text ?: "") + 1
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@ import com.intellij.psi.PsiFile
|
|||||||
|
|
||||||
class ReactJSXRainbowVisitor : XmlRainbowVisitor() {
|
class ReactJSXRainbowVisitor : XmlRainbowVisitor() {
|
||||||
|
|
||||||
override fun suitableForFile(file: PsiFile): Boolean {
|
override fun suitableForFile(file: PsiFile): Boolean {
|
||||||
return DialectDetector.isJSX(file)
|
return DialectDetector.isJSX(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clone(): HighlightVisitor {
|
override fun clone(): HighlightVisitor {
|
||||||
return ReactJSXRainbowVisitor()
|
return ReactJSXRainbowVisitor()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,87 +12,91 @@ import com.intellij.psi.xml.XmlTokenType
|
|||||||
|
|
||||||
open class XmlRainbowVisitor : RainbowHighlightVisitor() {
|
open class XmlRainbowVisitor : RainbowHighlightVisitor() {
|
||||||
|
|
||||||
override fun suitableForFile(file: PsiFile)
|
override fun suitableForFile(file: PsiFile)
|
||||||
: Boolean = super.suitableForFile(file) &&
|
: Boolean = super.suitableForFile(file) &&
|
||||||
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
RainbowSettings.instance.isEnableRainbowAngleBrackets &&
|
||||||
(file is XmlFile || file.viewProvider.allFiles.any { it is XmlFile })
|
(file is XmlFile || file.viewProvider.allFiles.any { it is XmlFile })
|
||||||
|
|
||||||
override fun clone(): HighlightVisitor = XmlRainbowVisitor()
|
override fun clone(): HighlightVisitor = XmlRainbowVisitor()
|
||||||
|
|
||||||
override fun visit(element: PsiElement) {
|
override fun visit(element: PsiElement) {
|
||||||
if (element !is XmlToken) {
|
if (element !is XmlToken) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
when (val tokenType = element.tokenType) {
|
when (val tokenType = element.tokenType) {
|
||||||
XmlTokenType.XML_DOCTYPE_START,
|
XmlTokenType.XML_DOCTYPE_START,
|
||||||
XmlTokenType.XML_DOCTYPE_END,
|
XmlTokenType.XML_DOCTYPE_END,
|
||||||
XmlTokenType.XML_PI_START,
|
XmlTokenType.XML_PI_START,
|
||||||
XmlTokenType.XML_PI_END -> {
|
XmlTokenType.XML_PI_END,
|
||||||
val startElement = element.takeIf {
|
-> {
|
||||||
tokenType == XmlTokenType.XML_DOCTYPE_START || tokenType == XmlTokenType.XML_PI_START
|
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
|
val endElement = element.takeIf {
|
||||||
}
|
tokenType == XmlTokenType.XML_DOCTYPE_END || tokenType == XmlTokenType.XML_PI_END
|
||||||
element.setHighlightInfo(element.xmlParent, 0, startElement, endElement)
|
}
|
||||||
}
|
element.setHighlightInfo(element.xmlParent, 0, startElement, endElement)
|
||||||
|
}
|
||||||
|
|
||||||
XmlTokenType.XML_START_TAG_START,
|
XmlTokenType.XML_START_TAG_START,
|
||||||
XmlTokenType.XML_END_TAG_START,
|
XmlTokenType.XML_END_TAG_START,
|
||||||
XmlTokenType.XML_TAG_END,
|
XmlTokenType.XML_TAG_END,
|
||||||
XmlTokenType.XML_EMPTY_ELEMENT_END -> {
|
XmlTokenType.XML_EMPTY_ELEMENT_END,
|
||||||
val startElement = element.takeIf { tokenType == XmlTokenType.XML_START_TAG_START }
|
-> {
|
||||||
val endElement = element.takeIf {
|
val startElement = element.takeIf { tokenType == XmlTokenType.XML_START_TAG_START }
|
||||||
tokenType == XmlTokenType.XML_TAG_END || tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END
|
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) }
|
}
|
||||||
}
|
element.level?.let { element.setHighlightInfo(element.xmlParent, it, startElement, endElement) }
|
||||||
|
}
|
||||||
|
|
||||||
XmlTokenType.XML_CDATA_START,
|
XmlTokenType.XML_CDATA_START,
|
||||||
XmlTokenType.XML_CDATA_END -> {
|
XmlTokenType.XML_CDATA_END,
|
||||||
val startElement = element.takeIf { tokenType == XmlTokenType.XML_CDATA_START }
|
-> {
|
||||||
val endElement = element.takeIf { tokenType == XmlTokenType.XML_CDATA_END }
|
val startElement = element.takeIf { tokenType == XmlTokenType.XML_CDATA_START }
|
||||||
element.level?.let { element.setHighlightInfo(element.parent, it + 1, startElement, endElement) }
|
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_TAG_NAME,
|
||||||
XmlTokenType.XML_NAME -> {
|
XmlTokenType.XML_NAME,
|
||||||
if (RainbowSettings.instance.rainbowifyTagNameInXML) {
|
-> {
|
||||||
val prevSibling = element.prevSibling
|
if (RainbowSettings.instance.rainbowifyTagNameInXML) {
|
||||||
if (prevSibling != null && prevSibling is XmlToken) {
|
val prevSibling = element.prevSibling
|
||||||
prevSibling.level?.let { element.setHighlightInfo(element.xmlParent, it, element, null) }
|
if (prevSibling != null && prevSibling is XmlToken) {
|
||||||
}
|
prevSibling.level?.let { element.setHighlightInfo(element.xmlParent, it, element, null) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val PsiElement.xmlParent: PsiElement?
|
val PsiElement.xmlParent: PsiElement?
|
||||||
get() {
|
get() {
|
||||||
var pElement = parent
|
var pElement = parent
|
||||||
while (pElement != null && pElement !is XmlTag && pElement !is PsiFile) {
|
while (pElement != null && pElement !is XmlTag && pElement !is PsiFile) {
|
||||||
pElement = pElement.parent
|
pElement = pElement.parent
|
||||||
}
|
}
|
||||||
|
|
||||||
return pElement
|
return pElement
|
||||||
}
|
}
|
||||||
|
|
||||||
tailrec fun iterateXmlTagParents(element: PsiElement?, count: Int): Int {
|
tailrec fun iterateXmlTagParents(element: PsiElement?, count: Int): Int {
|
||||||
if (element == null || element is PsiFile) {
|
if (element == null || element is PsiFile) {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextCount = count
|
var nextCount = count
|
||||||
if (element is XmlTag) {
|
if (element is XmlTag) {
|
||||||
nextCount++
|
nextCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
return iterateXmlTagParents(element.parent, nextCount)
|
return iterateXmlTagParents(element.parent, nextCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val XmlToken.level: Int?
|
private val XmlToken.level: Int?
|
||||||
get() = iterateXmlTagParents(parent, -1).takeIf { it >= 0 }
|
get() = iterateXmlTagParents(parent, -1).takeIf { it >= 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.ReactJSXRainbowVisitor"/>
|
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.ReactJSXRainbowVisitor" />
|
||||||
</extensions>
|
</extensions>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="JavaScript"
|
<bracePairProvider language="JavaScript"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.TSBracePairProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.TSBracePairProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,5 +1,5 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<annotator language="C#" implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.RainbowAnnotator"/>
|
<annotator language="C#" implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.RainbowAnnotator" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,10 +1,10 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="C#"
|
<bracePairProvider language="C#"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.CSharpBracePairProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.CSharpBracePairProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.CSharpRainbowVisitor"/>
|
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.CSharpRainbowVisitor" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,6 +1,6 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="Dart"
|
<bracePairProvider language="Dart"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.DartBracePairProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.DartBracePairProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,6 +1,6 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="GoTemplate"
|
<bracePairProvider language="GoTemplate"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.GoTemplateProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.GoTemplateProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,6 +1,6 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="Groovy"
|
<bracePairProvider language="Groovy"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.GroovyBracePairProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.GroovyBracePairProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,5 +1,5 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<annotator language="Haskell" implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.RainbowAnnotator"/>
|
<annotator language="Haskell" implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.RainbowAnnotator" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,5 +1,5 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.PugRainbowVisitor"/>
|
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.PugRainbowVisitor" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,12 +1,12 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="kotlin"
|
<bracePairProvider language="kotlin"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.KotlinBracePairProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.KotlinBracePairProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<annotator language="kotlin"
|
<annotator language="kotlin"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.KotlinLambdaExpressionArrowAnnotator"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.KotlinLambdaExpressionArrowAnnotator" />
|
||||||
<annotator language="kotlin"
|
<annotator language="kotlin"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.KotlinLabelAnnotator"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.annotator.KotlinLabelAnnotator" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,6 +1,6 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="ObjectiveC"
|
<bracePairProvider language="ObjectiveC"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.OCBracePairProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.OCBracePairProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,6 +1,6 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="izhangzhihao.rainbow.brackets">
|
<extensions defaultExtensionNs="com.chylex.coloredbrackets">
|
||||||
<bracePairProvider language="PHP"
|
<bracePairProvider language="PHP"
|
||||||
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.PHPBracePairProvider"/>
|
implementationClass="com.github.izhangzhihao.rainbow.brackets.provider.PHPBracePairProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -1,809 +1,81 @@
|
|||||||
<idea-plugin require-restart="true">
|
<idea-plugin require-restart="true">
|
||||||
<id>izhangzhihao.rainbow.brackets</id>
|
<id>com.chylex.coloredbrackets</id>
|
||||||
<name>Rainbow Brackets</name>
|
<name>Colored Brackets</name>
|
||||||
<vendor email="izhangzhihao@hotmail.com" url="https://github.com/izhangzhihao">izhangzhihao</vendor>
|
<vendor url="https://chylex.com">chylex</vendor>
|
||||||
|
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
<strong>🌈Rainbow Brackets for IntelliJ based IDEs/Android Studio/HUAWEI DevEco Studio</strong>
|
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>.
|
||||||
<br/>
|
]]></description>
|
||||||
|
|
||||||
<b>Sponsors</b>
|
<change-notes><![CDATA[
|
||||||
<p>This plugin is sponsored by <b>CodeStream</b></p>
|
<p>6.26</p>
|
||||||
|
<ul>
|
||||||
<a href=https://sponsorlink.codestream.com/?utm_source=jbmarket&utm_campaign=jbrainbowbrackets&utm_medium=banner>
|
<li>Original version the fork is based on.</li>
|
||||||
<img src=https://alt-images.codestream.com/codestream_logo_jbrainbowbrackets.png>
|
</ul>
|
||||||
</a>
|
]]></change-notes>
|
||||||
<br>Eliminate context switching and costly distractions. Create and merge PRs and perform code reviews from inside your IDE while using jump-to-definition, your keybindings, and other IDE favorites.
|
|
||||||
<a href=https://sponsorlink.codestream.com/?utm_source=jbmarket&utm_campaign=jbrainbowbrackets&utm_medium=banner>Learn more</a>
|
<depends>com.intellij.modules.lang</depends>
|
||||||
<br/>
|
<depends optional="true" config-file="kotlin-brackets.xml">org.jetbrains.kotlin</depends>
|
||||||
|
<depends optional="true" config-file="JSX.xml">JavaScript</depends>
|
||||||
<p>Supported languages:</p>
|
<depends optional="true" config-file="dart-brackets.xml">Dart</depends>
|
||||||
<p>Java, Scala, Clojure, Kotlin, Python, Haskell, Agda, Rust, JavaScript, TypeScript, Erlang, Go, Groovy, Ruby,
|
<depends optional="true" config-file="groovy-brackets.xml">org.intellij.groovy</depends>
|
||||||
Elixir, ObjectiveC, PHP, HTML, XML, SQL, Apex language, C#, Dart, Pug/Jade, Bash, Vue.js, C# Razor Pages, GLSL(the OpenGL Shading Language), Go Template, C++, C...</p>
|
<!--<depends optional="true" config-file="csharp-annotator.xml">com.intellij.modules.rider</depends>-->
|
||||||
<br/>
|
<depends optional="true" config-file="csharp-brackets.xml">com.intellij.modules.rider</depends>
|
||||||
<p>Author's choice:Rainbow Brackets + One Dark Theme + Nyan Progress Bar + Fira Code(Font)</p>
|
<depends optional="true" config-file="intellij-haskell-annotator.xml">intellij.haskell</depends>
|
||||||
<br/>
|
<depends optional="true" config-file="sql-brackets.xml">com.intellij.database</depends>
|
||||||
<p>
|
<depends optional="true" config-file="oc-brackets.xml">com.intellij.modules.clion</depends>
|
||||||
<img src="https://raw.githubusercontent.com/izhangzhihao/intellij-rainbow-brackets/2020.2/screenshots/with-java.png"
|
<depends optional="true" config-file="sh-brackets.xml">com.jetbrains.sh</depends>
|
||||||
border="0" width="500" height="205" alt="with-java"/></p>
|
<depends optional="true" config-file="php-brackets.xml">com.jetbrains.php</depends>
|
||||||
<p>
|
<depends optional="true" config-file="go-template-brackets.xml">org.jetbrains.plugins.go-template</depends>
|
||||||
<img src="https://raw.githubusercontent.com/izhangzhihao/intellij-rainbow-brackets/2020.2/screenshots/with-material-theme-ui.png"
|
<depends optional="true" config-file="jade-rainbow-visitor.xml">com.jetbrains.plugins.jade</depends>
|
||||||
border="0" width="500" height="167" alt="with-material-theme-ui.png"/></p>
|
<depends optional="true" config-file="python-brackets.xml">com.intellij.modules.python</depends>
|
||||||
<p>
|
|
||||||
<img src="https://raw.githubusercontent.com/izhangzhihao/intellij-rainbow-brackets/2020.2/screenshots/with-scala.png"
|
<extensionPoints>
|
||||||
border="0" width="500" height="250" alt="with-scala"/></p>
|
<extensionPoint name="bracePairProvider" beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
|
||||||
<p>
|
<with attribute="implementationClass"
|
||||||
<img src="https://raw.githubusercontent.com/izhangzhihao/intellij-rainbow-brackets/2020.2/screenshots/with-kotlin.png"
|
implements="com.github.izhangzhihao.rainbow.brackets.provider.BracePairProvider" />
|
||||||
border="0" width="500" height="191" alt="with-kotlin"/></p>
|
</extensionPoint>
|
||||||
<p>
|
</extensionPoints>
|
||||||
<img src="https://raw.githubusercontent.com/izhangzhihao/intellij-rainbow-brackets/2020.2/screenshots/with-Clojure.png"
|
|
||||||
border="0" width="500" height="190" alt="with-Clojure.png"/></p>
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<p>
|
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.DefaultRainbowVisitor" />
|
||||||
<img src="https://raw.githubusercontent.com/izhangzhihao/intellij-rainbow-brackets/2020.2/screenshots/with-HTML.png"
|
<highlightVisitor implementation="com.github.izhangzhihao.rainbow.brackets.visitor.XmlRainbowVisitor" />
|
||||||
border="0" width="500" height="112" alt="with-HTML.png"/></p>
|
|
||||||
<p>
|
<applicationConfigurable instance="com.github.izhangzhihao.rainbow.brackets.settings.RainbowConfigurable" displayName="Colored Brackets" parentId="appearance" />
|
||||||
<img src="https://user-images.githubusercontent.com/10737066/40234968-46593fe2-5adb-11e8-8ea8-0026fad86ca9.gif"
|
<applicationService
|
||||||
border="0" width="500" height="206" alt="Highlight current scope.gif"/></p>
|
serviceImplementation="com.github.izhangzhihao.rainbow.brackets.settings.RainbowSettings" />
|
||||||
<p>
|
<colorAndFontPanelFactory
|
||||||
<img src="https://user-images.githubusercontent.com/10737066/40235004-642dfe54-5adb-11e8-9fd7-648b92fab8f5.gif"
|
implementation="com.github.izhangzhihao.rainbow.brackets.settings.RainbowColorsPageFactory" />
|
||||||
border="0" width="500" height="206" alt="Highlight current scope.gif"/></p>
|
<colorAndFontDescriptorProvider
|
||||||
]]></description>
|
implementation="com.github.izhangzhihao.rainbow.brackets.settings.RainbowColorsPageFactory" />
|
||||||
|
|
||||||
<change-notes><![CDATA[
|
<additionalTextAttributes scheme="Default" file="colorSchemes/rainbow-color-default.xml" />
|
||||||
<p>6.26</p>
|
<additionalTextAttributes scheme="Darcula" file="colorSchemes/rainbow-color-default-darcula.xml" />
|
||||||
<ul>
|
<highlightingPassFactory implementation="com.github.izhangzhihao.rainbow.brackets.indents.RainbowIndentsPassFactory" />
|
||||||
<li>Bump dependencies.</li>
|
<editorNotificationProvider implementation="com.github.izhangzhihao.rainbow.brackets.RainbowifyBanner" />
|
||||||
</ul>
|
</extensions>
|
||||||
<br/>
|
|
||||||
|
<applicationListeners>
|
||||||
<p>6.25</p>
|
<listener class="com.github.izhangzhihao.rainbow.brackets.listener.RainbowColorsSchemeListener" topic="com.intellij.openapi.editor.colors.EditorColorsListener" />
|
||||||
<ul>
|
</applicationListeners>
|
||||||
<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>
|
<actions>
|
||||||
<br/>
|
<action class="com.github.izhangzhihao.rainbow.brackets.action.ScopeHighlightingAction"
|
||||||
|
id="Rainbow.ScopeHighlightingAction"
|
||||||
<p>6.24</p>
|
text="Highlight Current Scope"
|
||||||
<ul>
|
description="Highlight current scope.">
|
||||||
<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>
|
<mouse-shortcut keymap="$default" keystroke="control button3" />
|
||||||
</ul>
|
<mouse-shortcut keymap="Mac OS X" keystroke="meta button3" />
|
||||||
<br/>
|
<mouse-shortcut keymap="Mac OS X 10.5+" keystroke="meta button3" />
|
||||||
|
</action>
|
||||||
<p>6.23</p>
|
<action class="com.github.izhangzhihao.rainbow.brackets.action.ScopeOutsideHighlightingRestrainAction"
|
||||||
<ul>
|
id="Rainbow.ScopeOutsideHighlightingRestrainAction"
|
||||||
<li><a href="https://github.com/izhangzhihao/intellij-rainbow-brackets/issues/2465">#2465 Improved performance of `annotateUtil`.</a></li>
|
text="Restrain Scope Highlighting"
|
||||||
</ul>
|
description="Restrain outside of current scope highlighting.">
|
||||||
<br/>
|
<mouse-shortcut keymap="$default" keystroke="alt button3" />
|
||||||
|
<mouse-shortcut keymap="Mac OS X" keystroke="alt button3" />
|
||||||
<p>6.22</p>
|
<mouse-shortcut keymap="Mac OS X 10.5+" keystroke="alt button3" />
|
||||||
<ul>
|
</action>
|
||||||
<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>
|
</actions>
|
||||||
</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>
|
|
||||||
]]>
|
|
||||||
</change-notes>
|
|
||||||
|
|
||||||
<!-- please see http://confluence.jetbrains.com/display/IDEADEV/Build+Number+Ranges for description -->
|
|
||||||
<idea-version since-build="203" until-build="222.*"/>
|
|
||||||
|
|
||||||
<!-- 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-annotator.xml">com.intellij.modules.rider</depends>-->
|
|
||||||
<depends optional="true" config-file="csharp-brackets.xml">com.intellij.modules.rider</depends>
|
|
||||||
<depends optional="true" config-file="intellij-haskell-annotator.xml">intellij.haskell</depends>
|
|
||||||
<depends optional="true" config-file="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"/>
|
|
||||||
<postStartupActivity implementation="com.github.izhangzhihao.rainbow.brackets.RainbowUpdateNotifyActivity"/>
|
|
||||||
<!--<errorHandler implementation="com.github.izhangzhihao.rainbow.brackets.util.GitHubErrorReporter"/>-->
|
|
||||||
<highlightingPassFactory implementation="com.github.izhangzhihao.rainbow.brackets.indents.RainbowIndentsPassFactory"/>
|
|
||||||
<applicationService serviceImplementation="com.github.izhangzhihao.rainbow.brackets.ApplicationServicePlaceholder" id="ApplicationServicePlaceholder"/>
|
|
||||||
<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>
|
</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 |