Compare commits
11
Commits
1.0-SNAPSHOT
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b03aa0e497
|
||
|
|
251d94476c | ||
|
|
ff1fe83147 | ||
|
|
843fa8599e | ||
|
|
4e13722fb8
|
||
|
|
34756759b8
|
||
|
|
d9c92dd6d8 | ||
|
|
d215d7685c | ||
|
|
b5b4e421f1 | ||
|
|
af52826b6a | ||
|
|
7739a1835f |
No files matched your search
@@ -1,46 +0,0 @@
|
||||
# Java Gradle CircleCI 2.0 configuration file
|
||||
# See: https://circleci.com/docs/2.0/language-java/
|
||||
version: 2
|
||||
|
||||
# Define a job to be invoked later in a workflow.
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
|
||||
jobs:
|
||||
build:
|
||||
# Specify the execution environment. You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor
|
||||
docker:
|
||||
# specify the version you desire here
|
||||
- image: circleci/openjdk:11-jdk
|
||||
|
||||
# Specify service dependencies here if necessary
|
||||
# CircleCI maintains a library of pre-built images
|
||||
# documented at https://circleci.com/docs/2.0/circleci-images/
|
||||
# - image: circleci/postgres:9.4
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
environment:
|
||||
# Customize the JVM maximum heap limit
|
||||
JVM_OPTS: -Xmx3200m
|
||||
TERM: dumb
|
||||
# Add steps to the job
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#steps
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "build.gradle" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- v1-dependencies-
|
||||
|
||||
- run: gradle dependencies
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/.gradle
|
||||
key: v1-dependencies-{{ checksum "build.gradle" }}
|
||||
|
||||
# run tests!
|
||||
- run: gradle test
|
||||
@@ -0,0 +1,12 @@
|
||||
name: build
|
||||
on:
|
||||
push:
|
||||
branches: ['**']
|
||||
tags: ['v*']
|
||||
jobs:
|
||||
gradle:
|
||||
uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/gradle.yaml@v1
|
||||
with:
|
||||
java-version: '17'
|
||||
tasks: build
|
||||
artifacts: build/distributions/*.zip
|
||||
+1
-5
@@ -39,8 +39,4 @@ bin/
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
|
||||
### Directory with ssl key & cert - not to share to git! ###
|
||||
.signature
|
||||
|
||||
.DS_Store
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
<bytecodeTargetLevel target="17" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
-3
@@ -4,9 +4,6 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="delegatedBuild" value="true" />
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="JavadocBlankLines" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
||||
Generated
+5
@@ -16,5 +16,10 @@
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://repo.clojars.org/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+1
-7
@@ -1,13 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="SuppressKotlinCodeStyleNotification">
|
||||
<option name="disableForAll" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,45 +1,24 @@
|
||||
<!--
|
||||
~ Kingsrook IntelliJ Commentator Plugin
|
||||
~ Copyright (C) 2022. Kingsrook, LLC
|
||||
~ 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
~ contact@kingsrook.com
|
||||
~ https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU Affero General Public License as
|
||||
~ published by the Free Software Foundation, either version 3 of the
|
||||
~ License, or (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU Affero General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Affero General Public License
|
||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log"/>
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName"/>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$"/>
|
||||
<option name="externalSystemIdString" value="GRADLE"/>
|
||||
<option name="scriptParameters" value=""/>
|
||||
<option name="taskDescriptions">
|
||||
<list/>
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="runIde"/>
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value=""/>
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2"/>
|
||||
</configuration>
|
||||
<configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="runIde" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,3 +1,22 @@
|
||||
QQQ - Low-code Application Framework for Engineers
|
||||
Copyright (C) 2021-2025 QRun-IO, LLC
|
||||
https://www.qrun.io | https://github.com/QRun-IO
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
@@ -617,3 +636,45 @@ Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
@@ -3,12 +3,9 @@ IntelliJ plugin to provide code editing tools desired by the Kingsrook developme
|
||||
|
||||
Specifically:
|
||||
- Single-button to create a flower-box comment.
|
||||
|
||||
Future plans may include:
|
||||
- Auto-line-re-wrapping for flower-box comments.
|
||||
- Class/Method headers.
|
||||
- Language-aware and/or user-customizable comment-characters
|
||||
- Smart-case substitutions (e.g., MyVar myVar s/my/your/ = YourVar yourVar).
|
||||
- OK-version of auto-generation of getter, setter, and fluent-setter (wither?) methods
|
||||
- Simple decoder of URIs (e.g., to make abc%26123 into abc&123)
|
||||
|
||||
## License
|
||||
Kingsrook IntelliJ Commentator Plugin \
|
||||
|
||||
+51
-60
@@ -1,78 +1,69 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("java")
|
||||
id("org.jetbrains.intellij") version "1.5.2"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
id("java")
|
||||
id("org.jetbrains.kotlin.jvm") version "1.9.22"
|
||||
id("org.jetbrains.intellij") version "1.17.2"
|
||||
}
|
||||
|
||||
group = "com.kingsrook"
|
||||
version = "1.0-SNAPSHOT"
|
||||
version = "1.5.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
mavenCentral()
|
||||
maven {
|
||||
url = uri("https://repo.clojars.org/")
|
||||
}
|
||||
}
|
||||
|
||||
// Configure Gradle IntelliJ Plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin
|
||||
|
||||
// Configure Gradle IntelliJ Plugin
|
||||
// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
|
||||
intellij {
|
||||
version.set("2021.2")
|
||||
type.set("IC") // Target IDE Platform
|
||||
version.set("2024.1")
|
||||
type.set("IC") // Target IDE Platform
|
||||
|
||||
plugins.set(listOf(/* Plugin Dependencies */))
|
||||
plugins.set(listOf("com.intellij.java"))
|
||||
}
|
||||
|
||||
tasks {
|
||||
// Set the JVM compatibility versions
|
||||
withType<JavaCompile> {
|
||||
sourceCompatibility = "11"
|
||||
targetCompatibility = "11"
|
||||
}
|
||||
withType<JavaCompile> {
|
||||
sourceCompatibility = "17"
|
||||
targetCompatibility = "17"
|
||||
}
|
||||
|
||||
patchPluginXml {
|
||||
sinceBuild.set("212")
|
||||
untilBuild.set("222.*")
|
||||
}
|
||||
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "17"
|
||||
}
|
||||
|
||||
signPlugin {
|
||||
// certificateChainFile.set(File(System.getenv("CERTIFICATE_CHAIN_FILE")))
|
||||
// privateKeyFile.set(File(System.getenv("PRIVATE_KEY_FILE")))
|
||||
}
|
||||
patchPluginXml {
|
||||
sinceBuild.set("232")
|
||||
untilBuild.set("242.*")
|
||||
}
|
||||
|
||||
publishPlugin {
|
||||
token.set(System.getenv("PUBLISH_TOKEN"))
|
||||
}
|
||||
signPlugin {
|
||||
certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
|
||||
privateKey.set(System.getenv("PRIVATE_KEY"))
|
||||
password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
showStandardStreams = true
|
||||
}
|
||||
}
|
||||
publishPlugin {
|
||||
token.set(System.getenv("PUBLISH_TOKEN"))
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
// this option makes it so settings are searchable in the settings dialog
|
||||
// we don't have any at this time, so we don't care.
|
||||
// we're just turing this off, because it's breaking builds with it on for "who knows why"
|
||||
buildSearchableOptions {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("clojure-interop:java.awt:1.0.5")
|
||||
testImplementation(platform("org.junit:junit-bom:5.10.2"))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
|
||||
kotlin.stdlib.default.dependency = false
|
||||
|
||||
# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html
|
||||
org.gradle.configuration-cache = true
|
||||
|
||||
# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html
|
||||
org.gradle.caching = true
|
||||
Vendored
BIN
Binary file not shown.
+2
-22
@@ -1,26 +1,6 @@
|
||||
#
|
||||
# Kingsrook IntelliJ Commentator Plugin
|
||||
# Copyright (C) 2022. Kingsrook, LLC
|
||||
# 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
# contact@kingsrook.com
|
||||
# https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,24 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Kingsrook IntelliJ Commentator Plugin
|
||||
# Copyright (C) 2022. Kingsrook, LLC
|
||||
# 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
# contact@kingsrook.com
|
||||
# https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
|
||||
Vendored
+10
-15
@@ -1,22 +1,17 @@
|
||||
@rem
|
||||
@rem Kingsrook IntelliJ Commentator Plugin
|
||||
@rem Copyright (C) 2022. Kingsrook, LLC
|
||||
@rem 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
@rem contact@kingsrook.com
|
||||
@rem https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem This program is free software: you can redistribute it and/or modify
|
||||
@rem it under the terms of the GNU Affero General Public License as
|
||||
@rem published by the Free Software Foundation, either version 3 of the
|
||||
@rem License, or (at your option) any later version.
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem This program is distributed in the hope that it will be useful,
|
||||
@rem but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@rem GNU Affero General Public License for more details.
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem You should have received a copy of the GNU Affero General Public License
|
||||
@rem along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
|
||||
+6
-20
@@ -1,22 +1,8 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "intellij-commentator-plugin"
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public abstract class AbstractKRCommentatorEditorAction extends AnAction
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public AbstractKRCommentatorEditorAction(String title)
|
||||
{
|
||||
super(title);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public @NotNull ActionUpdateThread getActionUpdateThread()
|
||||
{
|
||||
return ActionUpdateThread.BGT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void update(AnActionEvent event)
|
||||
{
|
||||
////////////////////////////
|
||||
// Get required data keys //
|
||||
////////////////////////////
|
||||
final Project project = event.getProject();
|
||||
final Editor editor = event.getData(CommonDataKeys.EDITOR);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Set visibility only in case of existing project and editor and if some text in the editor is selected //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
event.getPresentation().setEnabled(project != null && editor != null);
|
||||
}
|
||||
}
|
||||
+462
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.CaretModel;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class CaseChangerAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
private static long lastCallTime = -1L;
|
||||
private static int lastTransformIndexUsed = 0;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** one
|
||||
** One
|
||||
** one
|
||||
** ONE
|
||||
**
|
||||
** twoThree
|
||||
** TwoThree
|
||||
** two_three
|
||||
** TWO_THREE
|
||||
** // two-three
|
||||
** // TWO-THREE
|
||||
*******************************************************************************/
|
||||
enum Transform
|
||||
{
|
||||
CAMEL_CASE,
|
||||
PASCAL_CASE,
|
||||
LOWER_CASE_UNDERSCORES,
|
||||
UPPER_CASE_UNDERSCORES,
|
||||
// LOWER_CASE_DASHES,
|
||||
// UPPER_CASE_DASHES
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public CaseChangerAction()
|
||||
{
|
||||
super("Case Changer");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public CaseChangerAction(String text)
|
||||
{
|
||||
super(text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
boolean reSelectAtEnd = (selectionModel.getSelectionStart() != selectionModel.getSelectionEnd());
|
||||
|
||||
////////////////////////////
|
||||
// do rotating transforms //
|
||||
////////////////////////////
|
||||
int transformIndexToUse = 0;
|
||||
if(System.currentTimeMillis() < lastCallTime + 1000)
|
||||
{
|
||||
transformIndexToUse = lastTransformIndexUsed + 1;
|
||||
}
|
||||
if(transformIndexToUse >= Transform.values().length)
|
||||
{
|
||||
transformIndexToUse = 0;
|
||||
}
|
||||
lastTransformIndexUsed = transformIndexToUse;
|
||||
Transform transform = Transform.values()[transformIndexToUse];
|
||||
|
||||
CaretModel caretModel = editor.getCaretModel();
|
||||
List<Caret> allCarets = caretModel.getAllCarets();
|
||||
System.out.println("there are [" + allCarets.size() + "] carets");
|
||||
if(allCarets.size() > 1)
|
||||
{
|
||||
for(Caret caret : allCarets)
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// expand selection to cover complete words //
|
||||
//////////////////////////////////////////////
|
||||
TextRange textRange = getTextRange(document, caret);
|
||||
int startOffset = textRange.getStartOffset();
|
||||
int endOffset = textRange.getEndOffset();
|
||||
|
||||
////////////////////////////////
|
||||
// build the replacement text //
|
||||
////////////////////////////////
|
||||
String inputText = document.getText(textRange);
|
||||
String replacementText = getReplacementText(inputText, transform);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
WriteCommandAction.runWriteCommandAction(project, () -> document.replaceString(startOffset, endOffset, replacementText));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// expand selection to cover complete words //
|
||||
//////////////////////////////////////////////
|
||||
TextRange textRange = getTextRange(document, selectionModel);
|
||||
int startOffset = textRange.getStartOffset();
|
||||
int endOffset = textRange.getEndOffset();
|
||||
|
||||
////////////////////////////////
|
||||
// build the replacement text //
|
||||
////////////////////////////////
|
||||
String inputText = document.getText(textRange);
|
||||
String replacementText = getReplacementText(inputText, transform);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
WriteCommandAction.runWriteCommandAction(project, () -> document.replaceString(startOffset, endOffset, replacementText));
|
||||
|
||||
/////////////////////////////////
|
||||
// re-select what was selected //
|
||||
/////////////////////////////////
|
||||
if(reSelectAtEnd)
|
||||
{
|
||||
int diff = replacementText.length() - inputText.length();
|
||||
selectionModel.setSelection(startOffset, endOffset + diff);
|
||||
}
|
||||
}
|
||||
|
||||
lastCallTime = System.currentTimeMillis();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
static String getReplacementText(String inputText, Transform transform)
|
||||
{
|
||||
StringBuilder rs = new StringBuilder();
|
||||
for(String word : toWords(inputText))
|
||||
{
|
||||
if(!word.isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
rs.append(switch(transform)
|
||||
{
|
||||
case CAMEL_CASE -> toCamelCase(word);
|
||||
case PASCAL_CASE -> toPascalCase(word);
|
||||
case LOWER_CASE_UNDERSCORES -> toCase(word, "_", String::toLowerCase);
|
||||
case UPPER_CASE_UNDERSCORES -> toCase(word, "_", String::toUpperCase);
|
||||
// case LOWER_CASE_DASHES -> toCase(inputText, "-", String::toLowerCase);
|
||||
// case UPPER_CASE_DASHES -> toCase(inputText, "-", String::toUpperCase);
|
||||
});
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
rs.append(word);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (rs.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* split a single "word" into its sub-words.
|
||||
* word being, separated by spaces.
|
||||
* subWord being, camelCase or under_score separated.
|
||||
*******************************************************************************/
|
||||
static List<String> toWords(String input)
|
||||
{
|
||||
List<String> rs = new ArrayList<>();
|
||||
StringBuilder currentWord = new StringBuilder();
|
||||
boolean inWord = false;
|
||||
boolean inNonWord = false;
|
||||
for(int i = 0; i < input.length(); i++)
|
||||
{
|
||||
char c = input.charAt(i);
|
||||
boolean isWordChar = isWordPart(c);
|
||||
if((isWordChar && inNonWord) || (!isWordChar && inWord))
|
||||
{
|
||||
rs.add(currentWord.toString());
|
||||
currentWord = new StringBuilder();
|
||||
}
|
||||
|
||||
currentWord.append(c);
|
||||
inWord = isWordChar;
|
||||
inNonWord = !inWord;
|
||||
}
|
||||
|
||||
rs.add(currentWord.toString());
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* split a single "word" into its sub-words.
|
||||
* word being, separated by spaces.
|
||||
* subWord being, camelCase or under_score separated.
|
||||
*******************************************************************************/
|
||||
static List<String> toSubWords(String input)
|
||||
{
|
||||
List<String> rs = new ArrayList<>();
|
||||
String[] words = input.split("[_]");
|
||||
|
||||
for(String word : words)
|
||||
{
|
||||
StringBuilder subWord = new StringBuilder();
|
||||
|
||||
boolean lastCharLower = false;
|
||||
boolean lastCharUpper = true;
|
||||
for(int j = 0; j < word.length(); j++)
|
||||
{
|
||||
char c = word.charAt(j);
|
||||
boolean thisCharLower = Character.isLowerCase(c);
|
||||
boolean thisCharUpper = Character.isUpperCase(c);
|
||||
|
||||
if(lastCharLower && thisCharUpper)
|
||||
{
|
||||
rs.add(subWord.toString());
|
||||
subWord = new StringBuilder();
|
||||
}
|
||||
|
||||
subWord.append(c);
|
||||
|
||||
lastCharLower = thisCharLower;
|
||||
lastCharUpper = thisCharUpper;
|
||||
}
|
||||
|
||||
if(!subWord.isEmpty())
|
||||
{
|
||||
rs.add(subWord.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static String toCamelCase(String input)
|
||||
{
|
||||
List<String> words = toSubWords(input);
|
||||
StringBuilder rs = new StringBuilder(words.get(0).toLowerCase());
|
||||
for(int i = 1; i < words.size(); i++)
|
||||
{
|
||||
rs.append(ucFirst(words.get(i).toLowerCase()));
|
||||
}
|
||||
return (rs.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static String ucFirst(String input)
|
||||
{
|
||||
return input.substring(0, 1).toUpperCase() + (input.length() > 1 ? input.substring(1) : "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static String toPascalCase(String input)
|
||||
{
|
||||
List<String> words = toSubWords(input);
|
||||
StringBuilder rs = new StringBuilder(ucFirst(words.get(0).toLowerCase()));
|
||||
for(int i = 1; i < words.size(); i++)
|
||||
{
|
||||
rs.append(ucFirst(words.get(i).toLowerCase()));
|
||||
}
|
||||
return (rs.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static String toCase(String input, String separator, Function<String, String> s)
|
||||
{
|
||||
List<String> words = toSubWords(input);
|
||||
StringBuilder rs = new StringBuilder(s.apply(words.get(0)));
|
||||
for(int i = 1; i < words.size(); i++)
|
||||
{
|
||||
rs.append(separator);
|
||||
rs.append(s.apply(words.get(i)));
|
||||
}
|
||||
return (rs.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
private static TextRange getTextRange(Document document, Caret caret)
|
||||
{
|
||||
int start = caret.getSelectionStart();
|
||||
int end = caret.getSelectionEnd();
|
||||
|
||||
if(start == end)
|
||||
{
|
||||
if(Character.isWhitespace(getChar(document, end)))
|
||||
{
|
||||
start--;
|
||||
}
|
||||
else
|
||||
{
|
||||
end++;
|
||||
}
|
||||
}
|
||||
|
||||
while(isWordPart(getChar(document, start)))
|
||||
{
|
||||
start--;
|
||||
}
|
||||
start++;
|
||||
|
||||
while(isWordPart(getChar(document, end)))
|
||||
{
|
||||
end++;
|
||||
}
|
||||
|
||||
TextRange textRange = new TextRange(start, end);
|
||||
System.out.println(start + "-" + end + ": [" + document.getText(textRange) + "]");
|
||||
return textRange;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
private static TextRange getTextRange(Document document, SelectionModel selectionModel)
|
||||
{
|
||||
int start = selectionModel.getSelectionStart();
|
||||
int end = selectionModel.getSelectionEnd();
|
||||
|
||||
if(start == end)
|
||||
{
|
||||
if(Character.isWhitespace(getChar(document, end)))
|
||||
{
|
||||
start--;
|
||||
}
|
||||
else
|
||||
{
|
||||
end++;
|
||||
}
|
||||
}
|
||||
|
||||
while(isWordPart(getChar(document, start)))
|
||||
{
|
||||
start--;
|
||||
}
|
||||
start++;
|
||||
|
||||
while(isWordPart(getChar(document, end)))
|
||||
{
|
||||
end++;
|
||||
}
|
||||
|
||||
TextRange textRange = new TextRange(start, end);
|
||||
System.out.println(start + "-" + end + ": [" + document.getText(textRange) + "]");
|
||||
return textRange;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static boolean isWordPart(char c)
|
||||
{
|
||||
// return (Character.isLetterOrDigit(c) || c == '_' || c == '-');
|
||||
return (Character.isLetterOrDigit(c) || c == '_');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static char getChar(Document document, int position)
|
||||
{
|
||||
TextRange textRange = new TextRange(position, position + 1);
|
||||
return (document.getText(textRange).charAt(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@ package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
@@ -31,14 +32,19 @@ import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.impl.cache.CacheUtil;
|
||||
import com.kingsrook.intellijcommentatorplugin.utils.CommentUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class CreateBoxCommentAction extends AnAction
|
||||
public class CreateBoxCommentAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -61,26 +67,6 @@ public class CreateBoxCommentAction extends AnAction
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void update(AnActionEvent event)
|
||||
{
|
||||
////////////////////////////
|
||||
// Get required data keys //
|
||||
////////////////////////////
|
||||
final Project project = event.getProject();
|
||||
final Editor editor = event.getData(CommonDataKeys.EDITOR);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Set visibility only in case of existing project and editor and if some text in the editor is selected //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
event.getPresentation().setVisible(project != null && editor != null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@@ -98,50 +84,14 @@ public class CreateBoxCommentAction extends AnAction
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
String commentChar = CommentUtils.getCommentChar(document);
|
||||
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// expand the selection upward as long as more comment lines are found //
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
while(selectionStartLine > 1)
|
||||
{
|
||||
TextRange lineAboveSelectionTextRange = new TextRange(document.getLineStartOffset(selectionStartLine - 1), document.getLineEndOffset(selectionStartLine - 1));
|
||||
String lineAbove = document.getText(lineAboveSelectionTextRange);
|
||||
|
||||
if(lineAbove.matches("^ *//.*"))
|
||||
{
|
||||
selectionStartLine--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// expand the selection downward as long as more comment lines are found //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
while(selectionEndLine < document.getLineNumber(document.getTextLength()) - 1)
|
||||
{
|
||||
TextRange lineBelowSelectionTextRange = new TextRange(document.getLineStartOffset(selectionEndLine + 1), document.getLineEndOffset(selectionEndLine + 1));
|
||||
String lineBelow = document.getText(lineBelowSelectionTextRange);
|
||||
|
||||
if(lineBelow.matches("^ *//.*"))
|
||||
{
|
||||
selectionEndLine++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
// expanded upward & downward as long as more comment lines are found //
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int selectionStartLine = CommentUtils.getSelectionStartLine(selectionModel, document, commentChar);
|
||||
int selectionEndLine = CommentUtils.getSelectionEndLine(selectionModel, document, commentChar);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
@@ -154,7 +104,7 @@ public class CreateBoxCommentAction extends AnAction
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
String commentLinesText = document.getText(textRange);
|
||||
StringBuilder replacementText = getReplacementText(commentLinesText);
|
||||
StringBuilder replacementText = getReplacementText(commentLinesText, commentChar);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
@@ -174,7 +124,7 @@ public class CreateBoxCommentAction extends AnAction
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
protected StringBuilder getReplacementText(String commentLinesText)
|
||||
protected StringBuilder getReplacementText(String commentLinesText, String commentChar)
|
||||
{
|
||||
String[] lines = commentLinesText.split("\n");
|
||||
Integer leastIndent = null;
|
||||
@@ -191,8 +141,8 @@ public class CreateBoxCommentAction extends AnAction
|
||||
////////////////////////////////////////////
|
||||
// strip away any leading or trailing /'s //
|
||||
////////////////////////////////////////////
|
||||
line = line.replaceAll("^( *)/+ *", "$1");
|
||||
line = line.replaceAll(" */+ *$", "");
|
||||
line = line.replaceAll("^( *)" + commentChar + "+ *", "$1");
|
||||
line = line.replaceAll(" *" + commentChar + "+ *$", "");
|
||||
|
||||
////////////////////////////////
|
||||
// strip away trailing spaces //
|
||||
@@ -278,7 +228,7 @@ public class CreateBoxCommentAction extends AnAction
|
||||
StringBuilder topAndBottom = new StringBuilder();
|
||||
for(int i = 0; i < longestLength + 6 - leastIndent; i++)
|
||||
{
|
||||
topAndBottom.append('/');
|
||||
topAndBottom.append(commentChar);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -295,23 +245,22 @@ public class CreateBoxCommentAction extends AnAction
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// start with an indent, then comment chars, then the text (minus the leading indention) //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
replacementText.append(indentString).append("// ").append(line.substring(leastIndent));
|
||||
StringBuilder replacementLine = new StringBuilder(indentString).append(commentChar).append(commentChar).append(" ").append(line.substring(Math.min(line.length(), leastIndent)));
|
||||
|
||||
//////////////////////////////////////
|
||||
// if padding is needed, add it now //
|
||||
//////////////////////////////////////
|
||||
if(line.length() < longestLength)
|
||||
while(replacementLine.length() < longestLength + 3)
|
||||
{
|
||||
for(int i = line.length(); i < longestLength; i++)
|
||||
{
|
||||
replacementText.append(' ');
|
||||
}
|
||||
replacementLine.append(' ');
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// finalize with comment chars and newline //
|
||||
/////////////////////////////////////////////
|
||||
replacementText.append(" //\n");
|
||||
replacementLine.append(" ").append(commentChar).append(commentChar).append("\n");
|
||||
|
||||
replacementText.append(replacementLine);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationGroupManager;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class GetSetWithAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public GetSetWithAction()
|
||||
{
|
||||
super("GetSetWith");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
// editor.getDocument().get
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
//////////////////////////////////////////
|
||||
int replacementStartOffset = document.getLineStartOffset(selectionStartLine);
|
||||
int replacementEndOffset = document.getLineEndOffset(selectionEndLine);
|
||||
TextRange textRange = new TextRange(replacementStartOffset, replacementEndOffset);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
String selectedLinesText = document.getText(textRange);
|
||||
|
||||
PsiElement element = (PsiElement) event.getDataContext().getData("psi.Element");
|
||||
PsiJavaFile parentOfType = PsiTreeUtil.getParentOfType(element, PsiJavaFile.class);
|
||||
|
||||
// JavaRecursiveElementWalkingVisitor visitor = new J
|
||||
|
||||
Document currentDoc = FileEditorManager.getInstance(project).getSelectedTextEditor().getDocument();
|
||||
VirtualFile currentFile = FileDocumentManager.getInstance().getFile(currentDoc);
|
||||
String className = currentFile.getNameWithoutExtension();
|
||||
|
||||
String[] selectedLines = selectedLinesText.split("\n");
|
||||
StringBuilder newMethodBodies = new StringBuilder();
|
||||
StringBuilder newMethodNames = new StringBuilder();
|
||||
int newMethodCounter = 0;
|
||||
for(String selectedLine : selectedLines)
|
||||
{
|
||||
System.out.println(selectedLine);
|
||||
Pair<String, String> typeNamePair = parseTypeAndNameFromDeclarationLine(selectedLine);
|
||||
if(typeNamePair == null)
|
||||
{
|
||||
System.out.println("Did not find a typeNamePair in selected line");
|
||||
continue;
|
||||
}
|
||||
|
||||
String type = typeNamePair.getKey();
|
||||
String name = typeNamePair.getValue();
|
||||
String nameUcFirst = ucFirst(name);
|
||||
boolean isStatic = isStatic(selectedLine);
|
||||
|
||||
if(needMethod(document, "get" + nameUcFirst))
|
||||
{
|
||||
newMethodBodies.append(writeGetter(isStatic, type, name, className));
|
||||
newMethodNames.append("get").append(nameUcFirst).append("\n");
|
||||
newMethodCounter++;
|
||||
}
|
||||
|
||||
if(!isFinal(selectedLine))
|
||||
{
|
||||
if(needMethod(document, "set" + nameUcFirst))
|
||||
{
|
||||
newMethodBodies.append(writeSetter(isStatic, type, name, className));
|
||||
newMethodNames.append("set").append(nameUcFirst).append("\n");
|
||||
newMethodCounter++;
|
||||
}
|
||||
|
||||
if(needMethod(document, "with" + nameUcFirst))
|
||||
{
|
||||
newMethodBodies.append(writeWither(isStatic, type, name, className));
|
||||
newMethodNames.append("with").append(nameUcFirst).append("\n");
|
||||
newMethodCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String notificationBody = "There were no GSW's to write...";
|
||||
if(newMethodCounter > 0)
|
||||
{
|
||||
int position = getJustBeforeClassClosePosition(document);
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(position, position, newMethodBodies.toString())
|
||||
);
|
||||
|
||||
/////////////////////////////////
|
||||
// un-select what was selected //
|
||||
/////////////////////////////////
|
||||
selectionModel.removeSelection();
|
||||
|
||||
notificationBody = "I wrote the following " + newMethodCounter + " GSW method" + (newMethodCounter == 1 ? "" : "s") + ":<br />" + newMethodNames;
|
||||
}
|
||||
|
||||
Notification notification = NotificationGroupManager.getInstance()
|
||||
.getNotificationGroup("Kingsrook Commentator Notifications")
|
||||
.createNotification(notificationBody, NotificationType.INFORMATION);
|
||||
notification.notify(project);
|
||||
|
||||
CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(2500);
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
// ok...
|
||||
System.out.println("interrupted");
|
||||
}
|
||||
notification.hideBalloon();
|
||||
return (true);
|
||||
});
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean isFinal(String line)
|
||||
{
|
||||
return (tokenizeLine(line).contains("final"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean isStatic(String line)
|
||||
{
|
||||
return (tokenizeLine(line).contains("static"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private int getJustBeforeClassClosePosition(Document document)
|
||||
{
|
||||
for(int lineNo = document.getLineCount() - 1; lineNo >= 1; lineNo--)
|
||||
{
|
||||
String lineText = document.getText(new TextRange(document.getLineStartOffset(lineNo), document.getLineEndOffset(lineNo)));
|
||||
if(lineText.trim().equals("}"))
|
||||
{
|
||||
return (document.getLineEndOffset(lineNo - 1));
|
||||
}
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void appendMethod(Project project, Document document, int position, String fullMethod)
|
||||
{
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(position, position, fullMethod)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String writeGetter(boolean isStatic, String fieldType, String fieldName, String className)
|
||||
{
|
||||
return "\n"
|
||||
+ "\n"
|
||||
+ " /*******************************************************************************\n"
|
||||
+ " ** Getter for " + fieldName + "\n"
|
||||
+ " *******************************************************************************/\n"
|
||||
+ " public " + fieldType + " get" + ucFirst(fieldName) + "()\n"
|
||||
+ " {\n"
|
||||
+ " return (" + (isStatic ? className : "this") + "." + fieldName + ");\n"
|
||||
+ " }\n"
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String writeSetter(boolean isStatic, String fieldType, String fieldName, String className)
|
||||
{
|
||||
return "\n"
|
||||
+ "\n"
|
||||
+ " /*******************************************************************************\n"
|
||||
+ " ** Setter for " + fieldName + "\n"
|
||||
+ " *******************************************************************************/\n"
|
||||
+ " public void set" + ucFirst(fieldName) + "(" + fieldType + " " + fieldName + ")\n"
|
||||
+ " {\n"
|
||||
+ " " + (isStatic ? className : "this") + "." + fieldName + " = " + fieldName + ";\n"
|
||||
+ " }\n"
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String writeWither(boolean isStatic, String fieldType, String fieldName, String className)
|
||||
{
|
||||
return "\n"
|
||||
+ "\n"
|
||||
+ " /*******************************************************************************\n"
|
||||
+ " ** Fluent setter for " + fieldName + "\n"
|
||||
+ " *******************************************************************************/\n"
|
||||
+ " public " + (isStatic ? "void" : className) + " with" + ucFirst(fieldName) + "(" + fieldType + " " + fieldName + ")\n"
|
||||
+ " {\n"
|
||||
+ " " + (isStatic ? className : "this") + "." + fieldName + " = " + fieldName + ";\n"
|
||||
+ (isStatic ? ""
|
||||
: " return (this);\n")
|
||||
+ " }\n"
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean needMethod(Document document, String methodName)
|
||||
{
|
||||
if(document.getText().matches("(?s).*public [\\w<, >\\[\\]]+ " + methodName + ".*"))
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String ucFirst(String name)
|
||||
{
|
||||
if(name == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
if(name.length() < 2)
|
||||
{
|
||||
return (name.toUpperCase());
|
||||
}
|
||||
return (name.substring(0, 1).toUpperCase() + name.substring(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static Pair<String, String> parseTypeAndNameFromDeclarationLine(String line)
|
||||
{
|
||||
List<String> tokens = tokenizeLine(line);
|
||||
if(tokens.size() > 1)
|
||||
{
|
||||
Pair<String, String> pair = Pair.of(tokens.get(tokens.size() - 2), tokens.get(tokens.size() - 1));
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// try to make sure each element looks like we expect it to... //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if(!pair.getValue().matches("[a-zA-Z_$][a-zA-Z0-9_$]*"))
|
||||
{
|
||||
System.out.format("But [%s] doesn't look like a variable name, so failing.\n", pair.getValue());
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(!pair.getKey().matches("[a-zA-Z0-9_$, .<>\\[\\]]+"))
|
||||
{
|
||||
System.out.format("But [%s] doesn't look like a type name, so failing.\n", pair.getKey());
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(pair.getKey().matches("(class|enum|interface)"))
|
||||
{
|
||||
System.out.format("But [%s] is a keyword, not a type name, so failing.\n", pair.getKey());
|
||||
return (null);
|
||||
}
|
||||
|
||||
return (pair);
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static List<String> tokenizeLine(String line)
|
||||
{
|
||||
String originalLine = line;
|
||||
line = line.replaceAll("//.*", "");
|
||||
line = line.replaceAll("\\*\\*.*", "");
|
||||
line = line.replaceAll("[=;].*", "");
|
||||
line = line.replaceAll(" +", " ");
|
||||
line = line.trim();
|
||||
|
||||
List<String> tokens = new ArrayList<>();
|
||||
StringBuilder currentToken = new StringBuilder();
|
||||
boolean insideAngleBrackets = false;
|
||||
for(char c : line.toCharArray())
|
||||
{
|
||||
if(c == '<')
|
||||
{
|
||||
insideAngleBrackets = true;
|
||||
currentToken.append(c);
|
||||
}
|
||||
else if(c == '>' && insideAngleBrackets)
|
||||
{
|
||||
insideAngleBrackets = false;
|
||||
currentToken.append(c);
|
||||
}
|
||||
else if(c == ' ' && insideAngleBrackets)
|
||||
{
|
||||
currentToken.append(c);
|
||||
}
|
||||
else if(c == ' ')
|
||||
{
|
||||
tokens.add(currentToken.toString());
|
||||
currentToken = new StringBuilder();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentToken.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(currentToken.length() > 0)
|
||||
{
|
||||
tokens.add(currentToken.toString());
|
||||
}
|
||||
|
||||
System.out.format("Parsed [%s] into [%s]\n", originalLine, tokens);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
}
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.CaretState;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class HeaderCommentAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public HeaderCommentAction()
|
||||
{
|
||||
super("Write Header Comment");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public HeaderCommentAction(String text)
|
||||
{
|
||||
super(text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
String commentChar = "*";
|
||||
String prefix = "/";
|
||||
String suffix = "/";
|
||||
String subsequentLineIndent = " ";
|
||||
try
|
||||
{
|
||||
VirtualFile currentFile = FileDocumentManager.getInstance().getFile(document);
|
||||
if(currentFile != null)
|
||||
{
|
||||
String fileName = currentFile.getPath();
|
||||
if(fileName.endsWith(".sh") || fileName.endsWith(".vtl") || fileName.endsWith(".vm") || fileName.endsWith(".pl") || fileName.endsWith(".properties"))
|
||||
{
|
||||
commentChar = "#";
|
||||
prefix = "";
|
||||
suffix = "";
|
||||
subsequentLineIndent = "";
|
||||
}
|
||||
else if(fileName.endsWith(".xml") || fileName.endsWith(".html"))
|
||||
{
|
||||
commentChar = "=";
|
||||
prefix = "<!-- ";
|
||||
suffix = " -->";
|
||||
subsequentLineIndent = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// leave default
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
//////////////////////////////////////////
|
||||
int replacementPoint = document.getLineStartOffset(selectionStartLine);
|
||||
String selectionLine = document.getText(new TextRange(document.getLineStartOffset(selectionStartLine), document.getLineEndOffset(selectionStartLine)));
|
||||
String indent = selectionLine.replaceAll("^( *).*", "$1");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
StringBuilder replacementText = getReplacementText(indent, commentChar, prefix, suffix, subsequentLineIndent);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(replacementPoint, replacementPoint, replacementText)
|
||||
);
|
||||
|
||||
/////////////////////////////////
|
||||
// un-select what was selected //
|
||||
/////////////////////////////////
|
||||
// selectionModel.removeSelection();
|
||||
// selectionModel.setSelection(replacementPoint, replacementPoint + 1);
|
||||
int caretPosition = document.getLineStartOffset(selectionStartLine + 1) + indent.length() + subsequentLineIndent.length() + 2;
|
||||
editor.getCaretModel().moveToOffset(caretPosition);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
protected StringBuilder getReplacementText(String indent, String commentChar, String prefix, String suffix, String subsequentLineIndent)
|
||||
{
|
||||
int prefixLength = 0;
|
||||
|
||||
StringBuilder rs = new StringBuilder(indent);
|
||||
if(prefix != null)
|
||||
{
|
||||
rs.append(prefix);
|
||||
prefixLength = prefix.length();
|
||||
}
|
||||
rs.append(commentChar.repeat(76 - prefixLength));
|
||||
rs.append("\n");
|
||||
|
||||
rs.append(indent);
|
||||
rs.append(Objects.requireNonNullElse(subsequentLineIndent, ""));
|
||||
rs.append(commentChar);
|
||||
rs.append(" ");
|
||||
rs.append("\n");
|
||||
|
||||
int suffixLength = suffix == null ? 0 : suffix.length();
|
||||
rs.append(indent);
|
||||
rs.append(Objects.requireNonNullElse(subsequentLineIndent, ""));
|
||||
rs.append(commentChar.repeat(76 - suffixLength));
|
||||
|
||||
if(suffix != null)
|
||||
{
|
||||
rs.append(suffix);
|
||||
}
|
||||
|
||||
rs.append("\n");
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationGroupManager;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class MyImporterAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
private static Map<String, String> importDefinitions = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
for(String junitAssertion : new String[] {
|
||||
"assertEquals",
|
||||
"assertNotEquals",
|
||||
"assertSame",
|
||||
"assertNotSame",
|
||||
"assertTrue",
|
||||
"assertFalse",
|
||||
"assertNull",
|
||||
"assertNotNull",
|
||||
"fail"
|
||||
})
|
||||
{
|
||||
importDefinitions.put(junitAssertion, "static org.junit.jupiter.api.Assertions." + junitAssertion);
|
||||
}
|
||||
|
||||
importDefinitions.put("assertThat", "static org.assertj.core.api.Assertions.assertThat");
|
||||
importDefinitions.put("assertThatThrownBy", "static org.assertj.core.api.Assertions.assertThatThrownBy");
|
||||
importDefinitions.put("File", "java.io.File");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public MyImporterAction()
|
||||
{
|
||||
super("MyImporter");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
//////////////////////////////////////
|
||||
// find imports already in the file //
|
||||
//////////////////////////////////////
|
||||
String documentText = document.getText();
|
||||
Set<String> existingImports = new HashSet<>();
|
||||
|
||||
int lineNo = 1;
|
||||
int lastImportPosition = 1;
|
||||
for(String line : documentText.split("\n"))
|
||||
{
|
||||
if(line.matches("^ *import .*"))
|
||||
{
|
||||
existingImports.add(line.replaceFirst("^ *import +", "").replaceFirst(";.*", ""));
|
||||
lastImportPosition = document.getLineEndOffset(lineNo);
|
||||
}
|
||||
lineNo++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
//////////////////////////////////////////
|
||||
int replacementStartOffset = document.getLineStartOffset(selectionStartLine);
|
||||
int replacementEndOffset = document.getLineEndOffset(selectionEndLine);
|
||||
TextRange textRange = new TextRange(replacementStartOffset, replacementEndOffset);
|
||||
|
||||
Set<String> addedImports = new LinkedHashSet<>();
|
||||
String selectedLinesText = document.getText(textRange);
|
||||
String[] words = selectedLinesText.split("\\b");
|
||||
for(String word : words)
|
||||
{
|
||||
if(importDefinitions.containsKey(word) && !existingImports.contains(importDefinitions.get(word)))
|
||||
{
|
||||
int finalLastImportPosition = lastImportPosition;
|
||||
String newLine = "import " + importDefinitions.get(word) + ";\n";
|
||||
WriteCommandAction.runWriteCommandAction(project, () -> document.replaceString(finalLastImportPosition, finalLastImportPosition, newLine));
|
||||
lastImportPosition += newLine.length();
|
||||
existingImports.add(importDefinitions.get(word));
|
||||
addedImports.add(word);
|
||||
}
|
||||
}
|
||||
|
||||
Notification notification = NotificationGroupManager.getInstance()
|
||||
.getNotificationGroup("Kingsrook Commentator Notifications")
|
||||
.createNotification(addedImports.isEmpty() ? "I couldn't find anything to import" : "I added imports for: " + addedImports, NotificationType.INFORMATION);
|
||||
notification.notify(project);
|
||||
|
||||
CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(2500);
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
// ok...
|
||||
System.out.println("interrupted");
|
||||
}
|
||||
notification.hideBalloon();
|
||||
return (true);
|
||||
});
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean isFinal(String line)
|
||||
{
|
||||
return (tokenizeLine(line).contains("final"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean isStatic(String line)
|
||||
{
|
||||
return (tokenizeLine(line).contains("static"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private int getJustBeforeClassClosePosition(Document document)
|
||||
{
|
||||
for(int lineNo = document.getLineCount() - 1; lineNo >= 1; lineNo--)
|
||||
{
|
||||
String lineText = document.getText(new TextRange(document.getLineStartOffset(lineNo), document.getLineEndOffset(lineNo)));
|
||||
if(lineText.trim().equals("}"))
|
||||
{
|
||||
return (document.getLineEndOffset(lineNo - 1));
|
||||
}
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void appendMethod(Project project, Document document, int position, String fullMethod)
|
||||
{
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(position, position, fullMethod)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String writeGetter(boolean isStatic, String fieldType, String fieldName, String className)
|
||||
{
|
||||
return "\n"
|
||||
+ "\n"
|
||||
+ " /*******************************************************************************\n"
|
||||
+ " ** Getter for " + fieldName + "\n"
|
||||
+ " *******************************************************************************/\n"
|
||||
+ " public " + fieldType + " get" + ucFirst(fieldName) + "()\n"
|
||||
+ " {\n"
|
||||
+ " return (" + (isStatic ? className : "this") + "." + fieldName + ");\n"
|
||||
+ " }\n"
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String writeSetter(boolean isStatic, String fieldType, String fieldName, String className)
|
||||
{
|
||||
return "\n"
|
||||
+ "\n"
|
||||
+ " /*******************************************************************************\n"
|
||||
+ " ** Setter for " + fieldName + "\n"
|
||||
+ " *******************************************************************************/\n"
|
||||
+ " public void set" + ucFirst(fieldName) + "(" + fieldType + " " + fieldName + ")\n"
|
||||
+ " {\n"
|
||||
+ " " + (isStatic ? className : "this") + "." + fieldName + " = " + fieldName + ";\n"
|
||||
+ " }\n"
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String writeWither(boolean isStatic, String fieldType, String fieldName, String className)
|
||||
{
|
||||
return "\n"
|
||||
+ "\n"
|
||||
+ " /*******************************************************************************\n"
|
||||
+ " ** Fluent setter for " + fieldName + "\n"
|
||||
+ " *******************************************************************************/\n"
|
||||
+ " public " + (isStatic ? "void" : className) + " with" + ucFirst(fieldName) + "(" + fieldType + " " + fieldName + ")\n"
|
||||
+ " {\n"
|
||||
+ " " + (isStatic ? className : "this") + "." + fieldName + " = " + fieldName + ";\n"
|
||||
+ (isStatic ? ""
|
||||
: " return (this);\n")
|
||||
+ " }\n"
|
||||
+ "\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private boolean needMethod(Document document, String methodName)
|
||||
{
|
||||
if(document.getText().matches("(?s).*public [\\w<, >\\[\\]]+ " + methodName + ".*"))
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String ucFirst(String name)
|
||||
{
|
||||
if(name == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
if(name.length() < 2)
|
||||
{
|
||||
return (name.toUpperCase());
|
||||
}
|
||||
return (name.substring(0, 1).toUpperCase() + name.substring(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static Pair<String, String> parseTypeAndNameFromDeclarationLine(String line)
|
||||
{
|
||||
List<String> tokens = tokenizeLine(line);
|
||||
if(tokens.size() > 1)
|
||||
{
|
||||
Pair<String, String> pair = Pair.of(tokens.get(tokens.size() - 2), tokens.get(tokens.size() - 1));
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// try to make sure each element looks like we expect it to... //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if(!pair.getValue().matches("[a-zA-Z_$][a-zA-Z0-9_$]*"))
|
||||
{
|
||||
System.out.format("But [%s] doesn't look like a variable name, so failing.\n", pair.getValue());
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(!pair.getKey().matches("[a-zA-Z0-9_$, .<>\\[\\]]+"))
|
||||
{
|
||||
System.out.format("But [%s] doesn't look like a type name, so failing.\n", pair.getKey());
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(pair.getKey().matches("(class|enum|interface)"))
|
||||
{
|
||||
System.out.format("But [%s] is a keyword, not a type name, so failing.\n", pair.getKey());
|
||||
return (null);
|
||||
}
|
||||
|
||||
return (pair);
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static List<String> tokenizeLine(String line)
|
||||
{
|
||||
String originalLine = line;
|
||||
line = line.replaceAll("//.*", "");
|
||||
line = line.replaceAll("\\*\\*.*", "");
|
||||
line = line.replaceAll("[=;].*", "");
|
||||
line = line.replaceAll(" +", " ");
|
||||
line = line.trim();
|
||||
|
||||
List<String> tokens = new ArrayList<>();
|
||||
StringBuilder currentToken = new StringBuilder();
|
||||
boolean insideAngleBrackets = false;
|
||||
for(char c : line.toCharArray())
|
||||
{
|
||||
if(c == '<')
|
||||
{
|
||||
insideAngleBrackets = true;
|
||||
currentToken.append(c);
|
||||
}
|
||||
else if(c == '>' && insideAngleBrackets)
|
||||
{
|
||||
insideAngleBrackets = false;
|
||||
currentToken.append(c);
|
||||
}
|
||||
else if(c == ' ' && insideAngleBrackets)
|
||||
{
|
||||
currentToken.append(c);
|
||||
}
|
||||
else if(c == ' ')
|
||||
{
|
||||
tokens.add(currentToken.toString());
|
||||
currentToken = new StringBuilder();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentToken.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(currentToken.length() > 0)
|
||||
{
|
||||
tokens.add(currentToken.toString());
|
||||
}
|
||||
|
||||
System.out.format("Parsed [%s] into [%s]\n", originalLine, tokens);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class SSAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
private String lastFind = null;
|
||||
private String lastReplace = null;
|
||||
|
||||
private List<FindReplacePair> history = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SSAction()
|
||||
{
|
||||
super("SmartSubstitute");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
static class FindReplacePair
|
||||
{
|
||||
String find;
|
||||
String replace;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public FindReplacePair(String find, String replace)
|
||||
{
|
||||
this.find = find;
|
||||
this.replace = replace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ss/" + find + "/" + replace + "/g";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
SSDialogWrapper dialog = new SSDialogWrapper(lastFind, lastReplace, history);
|
||||
dialog.show();
|
||||
|
||||
if(dialog.isOK() && dialog.getFind() != null && dialog.getReplace() != null)
|
||||
{
|
||||
updateDocument(event, dialog.getFind(), dialog.getReplace());
|
||||
lastFind = dialog.getFind();
|
||||
lastReplace = dialog.getReplace();
|
||||
history.add(new FindReplacePair(dialog.getFind(), dialog.getReplace()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void updateDocument(AnActionEvent event, String find, String replace)
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
//////////////////////////////////////////
|
||||
int replacementStartOffset = document.getLineStartOffset(selectionStartLine);
|
||||
int replacementEndOffset = document.getLineEndOffset(selectionEndLine);
|
||||
TextRange textRange = new TextRange(replacementStartOffset, replacementEndOffset);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
String selectedLinesText = document.getText(textRange);
|
||||
StringBuilder replacementText = getReplacementText(selectedLinesText, find, replace);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(replacementStartOffset, replacementEndOffset, replacementText)
|
||||
);
|
||||
|
||||
/////////////////////////////////
|
||||
// un-select what was selected //
|
||||
/////////////////////////////////
|
||||
selectionModel.removeSelection();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private StringBuilder getReplacementText(String text, String find, String replace)
|
||||
{
|
||||
if(text == null || text.trim().length() == 0)
|
||||
{
|
||||
return new StringBuilder(text);
|
||||
}
|
||||
|
||||
find = find.trim();
|
||||
String findRest = find.length() > 1 ? find.substring(1) : "";
|
||||
String lc1Find = find.substring(0, 1).toLowerCase() + findRest;
|
||||
String uc1Find = find.substring(0, 1).toUpperCase() + findRest;
|
||||
String ucFind = find.toUpperCase(); // todo - innerCammels to _'s
|
||||
|
||||
replace = replace == null ? "" : replace.trim();
|
||||
String replaceRest = replace.length() > 1 ? replace.substring(1) : "";
|
||||
String lc1Replace = replace.length() == 0 ? "" : (replace.substring(0, 1).toLowerCase() + replaceRest);
|
||||
String uc1Replace = replace.length() == 0 ? "" : (replace.substring(0, 1).toUpperCase() + replaceRest);
|
||||
String ucReplace = replace.toUpperCase();
|
||||
|
||||
return new StringBuilder(text
|
||||
.replaceAll(lc1Find, lc1Replace)
|
||||
.replaceAll(uc1Find, uc1Replace)
|
||||
.replaceAll(ucFind, ucReplace)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpringLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.util.List;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class SSDialogWrapper extends DialogWrapper
|
||||
{
|
||||
private final String initialFindText;
|
||||
private final String initialReplaceText;
|
||||
private final List<SSAction.FindReplacePair> history;
|
||||
|
||||
private String find;
|
||||
private String replace;
|
||||
|
||||
private JTextField findText;
|
||||
private JTextField replaceText;
|
||||
private ComboBox<SSAction.FindReplacePair> historyCombo;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SSDialogWrapper(String initialFindText, String initialReplaceText, List<SSAction.FindReplacePair> history)
|
||||
{
|
||||
super(true);
|
||||
|
||||
this.initialFindText = initialFindText;
|
||||
this.initialReplaceText = initialReplaceText;
|
||||
this.history = history;
|
||||
|
||||
setTitle("SmartSubstitute");
|
||||
setSize(350, 190); // todo - was 155
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public @Nullable JComponent getPreferredFocusedComponent()
|
||||
{
|
||||
return findText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
protected JComponent createCenterPanel()
|
||||
{
|
||||
JPanel dialogPanel = new JPanel();
|
||||
|
||||
////////////////////////
|
||||
// find label & field //
|
||||
////////////////////////
|
||||
JLabel findLabel = new JLabel("Find:");
|
||||
findLabel.setPreferredSize(new Dimension(60, 30));
|
||||
dialogPanel.add(findLabel);
|
||||
|
||||
findText = new JTextField();
|
||||
findText.setPreferredSize(new Dimension(255, 30));
|
||||
findText.addFocusListener(new SelectOnFocus(findText));
|
||||
if(initialFindText != null)
|
||||
{
|
||||
findText.setText(initialFindText);
|
||||
}
|
||||
dialogPanel.add(findText);
|
||||
|
||||
///////////////////////////
|
||||
// replace label & field //
|
||||
///////////////////////////
|
||||
JLabel replaceLabel = new JLabel("Replace:");
|
||||
replaceLabel.setPreferredSize(findLabel.getPreferredSize());
|
||||
dialogPanel.add(replaceLabel);
|
||||
|
||||
replaceText = new JTextField();
|
||||
replaceText.setPreferredSize(findText.getPreferredSize());
|
||||
replaceText.addFocusListener(new SelectOnFocus(replaceText));
|
||||
if(initialReplaceText != null)
|
||||
{
|
||||
replaceText.setText(initialReplaceText);
|
||||
}
|
||||
dialogPanel.add(replaceText);
|
||||
|
||||
///////////////////////////
|
||||
// history label & field //
|
||||
///////////////////////////
|
||||
JLabel historyLabel = new JLabel("History:");
|
||||
historyLabel.setPreferredSize(findLabel.getPreferredSize());
|
||||
dialogPanel.add(historyLabel);
|
||||
|
||||
historyCombo = new ComboBox<>(history.stream().toArray(SSAction.FindReplacePair[]::new));
|
||||
if(history.size() > 0)
|
||||
{
|
||||
historyCombo.setItem(history.get(history.size() - 1));
|
||||
}
|
||||
historyCombo.setPreferredSize(findText.getPreferredSize());
|
||||
historyCombo.addActionListener(new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
SSAction.FindReplacePair item = historyCombo.getItem();
|
||||
if(item != null)
|
||||
{
|
||||
findText.setText(item.find);
|
||||
replaceText.setText(item.replace);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogPanel.add(historyCombo);
|
||||
|
||||
SpringLayout layout = new SpringLayout();
|
||||
dialogPanel.setLayout(layout);
|
||||
int padding = 6;
|
||||
|
||||
/////////////////////////////
|
||||
// place find label & text //
|
||||
/////////////////////////////
|
||||
layout.putConstraint(SpringLayout.WEST, findLabel, padding, SpringLayout.WEST, dialogPanel);
|
||||
layout.putConstraint(SpringLayout.NORTH, findLabel, padding, SpringLayout.NORTH, dialogPanel);
|
||||
|
||||
layout.putConstraint(SpringLayout.WEST, findText, padding, SpringLayout.EAST, findLabel);
|
||||
layout.putConstraint(SpringLayout.NORTH, findText, padding, SpringLayout.NORTH, dialogPanel);
|
||||
|
||||
////////////////////////////////
|
||||
// place replace label & text //
|
||||
////////////////////////////////
|
||||
layout.putConstraint(SpringLayout.WEST, replaceLabel, padding, SpringLayout.WEST, dialogPanel);
|
||||
layout.putConstraint(SpringLayout.NORTH, replaceLabel, padding, SpringLayout.SOUTH, findLabel);
|
||||
|
||||
layout.putConstraint(SpringLayout.WEST, replaceText, padding, SpringLayout.EAST, replaceLabel);
|
||||
layout.putConstraint(SpringLayout.NORTH, replaceText, padding, SpringLayout.SOUTH, findText);
|
||||
|
||||
////////////////////////////////
|
||||
// place history label & text //
|
||||
////////////////////////////////
|
||||
layout.putConstraint(SpringLayout.WEST, historyLabel, padding, SpringLayout.WEST, dialogPanel);
|
||||
layout.putConstraint(SpringLayout.NORTH, historyLabel, padding, SpringLayout.SOUTH, replaceLabel);
|
||||
|
||||
layout.putConstraint(SpringLayout.WEST, historyCombo, padding, SpringLayout.EAST, historyLabel);
|
||||
layout.putConstraint(SpringLayout.NORTH, historyCombo, padding, SpringLayout.SOUTH, replaceText);
|
||||
|
||||
return (dialogPanel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static class SelectOnFocus implements FocusListener
|
||||
{
|
||||
private final JTextField field;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public SelectOnFocus(JTextField field)
|
||||
{
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void focusGained(FocusEvent e)
|
||||
{
|
||||
field.selectAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void focusLost(FocusEvent e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void show()
|
||||
{
|
||||
super.show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
protected void doOKAction()
|
||||
{
|
||||
find = findText.getText();
|
||||
replace = replaceText.getText();
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for find
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getFind()
|
||||
{
|
||||
return find;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for replace
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getReplace()
|
||||
{
|
||||
return replace;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiIdentifier;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class StubSetterCallsAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StubSetterCallsAction()
|
||||
{
|
||||
super("StubSetterCalls");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
//////////////////////////////////////////
|
||||
int startOffset = document.getLineStartOffset(selectionStartLine);
|
||||
int endOffset = document.getLineEndOffset(selectionEndLine);
|
||||
|
||||
String line = document.getText(new TextRange(document.getLineStartOffset(selectionEndLine), document.getLineEndOffset(selectionEndLine)));
|
||||
String leadingWhitespace = line.replaceAll("\\S.*", "");
|
||||
|
||||
int caretOffset = editor.getCaretModel().getOffset();
|
||||
PsiFile psiFile = event.getData(CommonDataKeys.PSI_FILE);
|
||||
if(psiFile == null)
|
||||
{
|
||||
System.out.println("No PSI file...");
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement psiElement = psiFile.findElementAt(caretOffset);
|
||||
if(psiElement == null)
|
||||
{
|
||||
System.out.println("No PSI element...");
|
||||
return;
|
||||
}
|
||||
|
||||
if(psiElement instanceof PsiIdentifier)
|
||||
{
|
||||
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
|
||||
String className = javaPsiFacade.getElementFactory().createExpressionFromText(psiElement.getText(), psiElement).getType().getCanonicalText();
|
||||
PsiClass varClass = javaPsiFacade.findClass(className, GlobalSearchScope.allScope(project));
|
||||
|
||||
StringBuilder appendText = new StringBuilder("\n");
|
||||
for(PsiMethod method : varClass.getMethods())
|
||||
{
|
||||
if(method.getName().startsWith("set"))
|
||||
{
|
||||
appendText.append(leadingWhitespace).append(psiElement.getText()).append(".").append(method.getName()).append("();\n");
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// String selectedLinesText = document.getText(textRange);
|
||||
// String replacementText = getReplacementText(selectedLinesText);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
// WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
// document.replaceString(startOffset, endOffset, replacementText)
|
||||
// );
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
{
|
||||
document.replaceString(endOffset, endOffset, appendText);
|
||||
});
|
||||
|
||||
/////////////////////////////////
|
||||
// un-select what was selected //
|
||||
/////////////////////////////////
|
||||
selectionModel.removeSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Not an identifier...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getReplacementText(String selectedLinesText)
|
||||
{
|
||||
System.out.println(selectedLinesText);
|
||||
return (selectedLinesText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class URIDecodeAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public URIDecodeAction()
|
||||
{
|
||||
super("URIDecode");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
//////////////////////////////////////////
|
||||
int startOffset = document.getLineStartOffset(selectionStartLine);
|
||||
int endOffset = document.getLineEndOffset(selectionEndLine);
|
||||
TextRange textRange = new TextRange(startOffset, endOffset);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
String selectedLinesText = document.getText(textRange);
|
||||
StringBuilder replacementText = getReplacementText(selectedLinesText);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(startOffset, endOffset, replacementText)
|
||||
);
|
||||
|
||||
/////////////////////////////////
|
||||
// un-select what was selected //
|
||||
/////////////////////////////////
|
||||
selectionModel.removeSelection();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StringBuilder getReplacementText(String selectedLinesText)
|
||||
{
|
||||
StringBuilder rs = new StringBuilder();
|
||||
for(int i = 0; i < selectedLinesText.length(); i++)
|
||||
{
|
||||
char c = selectedLinesText.charAt(i);
|
||||
if(c == '%' && i < selectedLinesText.length() - 2)
|
||||
{
|
||||
String hex = selectedLinesText.substring(i + 1, i + 3);
|
||||
char replacement = (char) Integer.parseInt(hex, 16);
|
||||
rs.append(replacement);
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs.append(c);
|
||||
}
|
||||
}
|
||||
return (rs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class WordToSnakeCaseAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public WordToSnakeCaseAction()
|
||||
{
|
||||
super("WordToSnakeCase");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
////////////////////////////////////////////////////////////////
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
// todo - if a selection range, that whole range, but if just 1 char, then that word
|
||||
//////////////////////////////////////////
|
||||
int startOffset = document.getLineStartOffset(selectionStartLine);
|
||||
int endOffset = document.getLineEndOffset(selectionEndLine);
|
||||
TextRange textRange = new TextRange(startOffset, endOffset);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
String selectedLinesText = document.getText(textRange);
|
||||
StringBuilder replacementText = getReplacementText(selectedLinesText);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(startOffset, endOffset, replacementText)
|
||||
);
|
||||
|
||||
/////////////////////////////////
|
||||
// un-select what was selected //
|
||||
/////////////////////////////////
|
||||
selectionModel.removeSelection();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public StringBuilder getReplacementText(String selectedLinesText)
|
||||
{
|
||||
StringBuilder rs = new StringBuilder();
|
||||
for(int i = 0; i < selectedLinesText.length(); i++)
|
||||
{
|
||||
// todo - camelCase to camel_case, etc...
|
||||
char c = selectedLinesText.charAt(i);
|
||||
if(c == '%' && i < selectedLinesText.length() - 2)
|
||||
{
|
||||
String hex = selectedLinesText.substring(i + 1, i + 3);
|
||||
char replacement = (char) Integer.parseInt(hex, 16);
|
||||
rs.append(replacement);
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs.append(c);
|
||||
}
|
||||
}
|
||||
return (rs);
|
||||
}
|
||||
}
|
||||
+575
@@ -0,0 +1,575 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.kingsrook.intellijcommentatorplugin.settings.CommentatorSettingsState;
|
||||
import com.kingsrook.intellijcommentatorplugin.utils.CommentUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class WrapCommentAction extends AbstractKRCommentatorEditorAction
|
||||
{
|
||||
private int maxLength = 94;
|
||||
private int minLength = 54;
|
||||
|
||||
private static long lastCallTime = -1L;
|
||||
private static int lastTransformIndexUsed = 0;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
enum Transform
|
||||
{
|
||||
DO_NOT_REWRAP,
|
||||
DO_REWRAP
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public WrapCommentAction()
|
||||
{
|
||||
super("Wrap Comment");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public WrapCommentAction(String text)
|
||||
{
|
||||
super(text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void readSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
CommentatorSettingsState settings = CommentatorSettingsState.getInstance();
|
||||
maxLength = settings.wrapCommentMaxWidth;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void actionPerformed(AnActionEvent event)
|
||||
{
|
||||
readSettings();
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Get all the required data from data keys //
|
||||
//////////////////////////////////////////////
|
||||
Editor editor = event.getRequiredData(CommonDataKeys.EDITOR);
|
||||
Project project = event.getProject();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Access document, caret, and selection //
|
||||
///////////////////////////////////////////
|
||||
Document document = editor.getDocument();
|
||||
SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
String commentChar = CommentUtils.getCommentChar(document);
|
||||
|
||||
////////////////////////////
|
||||
// do rotating transforms //
|
||||
////////////////////////////
|
||||
int transformIndexToUse = 0;
|
||||
if(System.currentTimeMillis() < lastCallTime + 1000)
|
||||
{
|
||||
transformIndexToUse = lastTransformIndexUsed + 1;
|
||||
}
|
||||
if(transformIndexToUse >= Transform.values().length)
|
||||
{
|
||||
transformIndexToUse = 0;
|
||||
}
|
||||
lastTransformIndexUsed = transformIndexToUse;
|
||||
Transform transform = Transform.values()[transformIndexToUse];
|
||||
lastCallTime = System.currentTimeMillis();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// find the start & end lines, based on selection start & end //
|
||||
// expanded upward & downward as long as more comment lines are found //
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int selectionStartLine = CommentUtils.getSelectionStartLine(selectionModel, document, commentChar);
|
||||
int selectionEndLine = CommentUtils.getSelectionEndLine(selectionModel, document, commentChar);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// get the range of text being replaced //
|
||||
//////////////////////////////////////////
|
||||
int replacementStartOffset = document.getLineStartOffset(selectionStartLine);
|
||||
int replacementEndOffset = document.getLineEndOffset(selectionEndLine);
|
||||
TextRange textRange = new TextRange(replacementStartOffset, replacementEndOffset);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// build the replacement text, feeding it the comment-lines as input //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
String commentLinesText = document.getText(textRange);
|
||||
StringBuilder replacementText = getReplacementText(commentLinesText, commentChar, transform, maxLength);
|
||||
|
||||
//////////////////////////
|
||||
// make the replacement //
|
||||
//////////////////////////
|
||||
WriteCommandAction.runWriteCommandAction(project, () ->
|
||||
document.replaceString(replacementStartOffset, replacementEndOffset, replacementText)
|
||||
);
|
||||
|
||||
/////////////////////////////////
|
||||
// un-select what was selected //
|
||||
/////////////////////////////////
|
||||
selectionModel.removeSelection();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
StringBuilder getReplacementText(String commentLinesText, String commentChar, Transform transform, int length)
|
||||
{
|
||||
if(transform == Transform.DO_REWRAP)
|
||||
{
|
||||
return getReplacementDoingRewrap(commentLinesText, commentChar);
|
||||
}
|
||||
|
||||
String[] lines = commentLinesText.split("\n");
|
||||
Integer leastIndent = null;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// iterate over the input lines, building a list of lines to be in the replacement text. //
|
||||
// note that the header & footer will not be in the replacementLines list //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
List<String> replacementLines = new LinkedList<>();
|
||||
for(int i = 0; i < lines.length; i++)
|
||||
{
|
||||
String line = lines[i];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// find the indent of this line - see if it's the least we've found //
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
int lineIndent = 0;
|
||||
for(int c = 0; c < line.length(); c++)
|
||||
{
|
||||
if(line.charAt(c) != ' ')
|
||||
{
|
||||
lineIndent = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(leastIndent == null || lineIndent < leastIndent)
|
||||
{
|
||||
leastIndent = lineIndent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
// strip away any leading or trailing /'s //
|
||||
////////////////////////////////////////////
|
||||
line = line.replaceAll("^( *)" + commentChar + "+ ?", ""); // used to be "$1" for RHS
|
||||
line = line.replaceAll(" *" + commentChar + "+ *$", "");
|
||||
|
||||
////////////////////////////////
|
||||
// strip away trailing spaces //
|
||||
////////////////////////////////
|
||||
line = line.replaceAll(" *$", "");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if the line is empty, and it's the first or last, then assume it was a previous header/footer, //
|
||||
// and leave it out of the replacementLines list //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
boolean lineIsEmpty = line.trim().length() == 0;
|
||||
|
||||
if(lineIsEmpty)
|
||||
{
|
||||
if(i == 0 || i == lines.length - 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
replacementLines.add(line);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// else, if not first or last line, skip empty lines when computing indent and lengths //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(lineIsEmpty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// ensure a least-indent value was found //
|
||||
///////////////////////////////////////////
|
||||
if(leastIndent == null)
|
||||
{
|
||||
leastIndent = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// build the string to be inserted before all lines as the indent //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
StringBuilder indentString = new StringBuilder();
|
||||
for(int i = 0; i < leastIndent; i++)
|
||||
{
|
||||
indentString.append(' ');
|
||||
}
|
||||
|
||||
// System.out.println(replacementLines);
|
||||
replacementLines = manipulateLines(replacementLines, length);
|
||||
|
||||
///////////////////////////
|
||||
// find the longest line //
|
||||
///////////////////////////
|
||||
Integer longestLength = 0;
|
||||
for(String line : replacementLines)
|
||||
{
|
||||
if(line.length() > longestLength)
|
||||
{
|
||||
longestLength = line.length();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// build the top & bottom line for the boxes and do other things //
|
||||
///////////////////////////////////////////////////////////////////
|
||||
StringBuilder topAndBottom = new StringBuilder();
|
||||
for(int i = 0; i < longestLength + 6; i++)
|
||||
{
|
||||
topAndBottom.append(commentChar);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// start building our replacement text with an (indented) header line //
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
StringBuilder replacementText = new StringBuilder(indentString);
|
||||
replacementText.append(topAndBottom).append("\n");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// loop over the replacement lines, building final output //
|
||||
////////////////////////////////////////////////////////////
|
||||
for(String line : replacementLines)
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// start with an indent, then comment chars, then the text (minus the leading indention) //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
StringBuilder replacementLine = new StringBuilder(indentString).append(commentChar).append(commentChar).append(" ").append(line);
|
||||
|
||||
//////////////////////////////////////
|
||||
// if padding is needed, add it now //
|
||||
//////////////////////////////////////
|
||||
while(replacementLine.length() < indentString.length() + longestLength + 3)
|
||||
{
|
||||
replacementLine.append(' ');
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// finalize with comment chars and newline //
|
||||
/////////////////////////////////////////////
|
||||
replacementLine.append(" ").append(commentChar).append(commentChar).append("\n");
|
||||
|
||||
replacementText.append(replacementLine);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// add a final bottom line of all comment chars //
|
||||
//////////////////////////////////////////////////
|
||||
replacementText.append(indentString).append(topAndBottom);
|
||||
|
||||
return replacementText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private StringBuilder getReplacementDoingRewrap(String commentLinesText, String commentChar)
|
||||
{
|
||||
StringBuilder best = null;
|
||||
int bestLineCount = Integer.MAX_VALUE;
|
||||
|
||||
for(int length = maxLength; length >= minLength; length--)
|
||||
{
|
||||
StringBuilder candidate = getReplacementText(commentLinesText, commentChar, Transform.DO_NOT_REWRAP, length);
|
||||
int candidateLineCount = candidate.toString().split("\n").length;
|
||||
if(candidateLineCount <= bestLineCount)
|
||||
{
|
||||
best = candidate;
|
||||
bestLineCount = candidateLineCount;
|
||||
}
|
||||
}
|
||||
|
||||
return (best);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
protected List<String> manipulateLines(List<String> inputLines, int length)
|
||||
{
|
||||
List<String> words = new ArrayList<>();
|
||||
List<String> spaceAfterWords = new ArrayList<>();
|
||||
List<Boolean> newlinesAfterWords = new ArrayList<>();
|
||||
|
||||
StringBuilder currentWord = null;
|
||||
int spacesAfterWord = 0;
|
||||
for(String inputLine : inputLines)
|
||||
{
|
||||
for(int i = 0; i < inputLine.length(); i++)
|
||||
{
|
||||
char c = inputLine.charAt(i);
|
||||
if(currentWord == null)
|
||||
{
|
||||
currentWord = new StringBuilder().append(c);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// deal with multiple spaces together at start of line //
|
||||
/////////////////////////////////////////////////////////
|
||||
if(c == ' ')
|
||||
{
|
||||
while(i < inputLine.length() - 1 && inputLine.charAt(i + 1) == ' ')
|
||||
{
|
||||
currentWord.append(' ');
|
||||
i++;
|
||||
}
|
||||
if(currentWord.toString().matches("^ +$"))
|
||||
{
|
||||
words.add(currentWord.toString());
|
||||
spaceAfterWords.add(String.join("", Collections.nCopies(spacesAfterWord, " ")));
|
||||
newlinesAfterWords.add(false);
|
||||
currentWord = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(spacesAfterWord > 0)
|
||||
{
|
||||
if(c == ' ')
|
||||
{
|
||||
////////////////////////////////
|
||||
// multiple spaces after word //
|
||||
////////////////////////////////
|
||||
spacesAfterWord++;
|
||||
}
|
||||
else
|
||||
{
|
||||
////////////////////////
|
||||
// start of next word //
|
||||
////////////////////////
|
||||
words.add(currentWord.toString());
|
||||
spaceAfterWords.add(String.join("", Collections.nCopies(spacesAfterWord, " ")));
|
||||
newlinesAfterWords.add(false);
|
||||
currentWord = new StringBuilder().append(c);
|
||||
spacesAfterWord = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(c == ' ')
|
||||
{
|
||||
spacesAfterWord = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentWord.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(currentWord != null)
|
||||
{
|
||||
words.add(currentWord.toString());
|
||||
spaceAfterWords.add(String.join("", Collections.nCopies(spacesAfterWord, " ")));
|
||||
|
||||
char lastChar = currentWord.charAt(currentWord.length() - 1);
|
||||
if(lastChar == '.' || lastChar == '?' || lastChar == '!')
|
||||
{
|
||||
newlinesAfterWords.add(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
newlinesAfterWords.add(false);
|
||||
}
|
||||
|
||||
currentWord = null;
|
||||
spacesAfterWord = 0;
|
||||
}
|
||||
}
|
||||
|
||||
List<String> outputLines = new ArrayList<>();
|
||||
StringBuilder outputLine = null;
|
||||
|
||||
////////////////////////////////////////////
|
||||
// loop over words, building output lines //
|
||||
////////////////////////////////////////////
|
||||
for(int i = 0; i < words.size(); i++)
|
||||
{
|
||||
// System.out.format("[%s][%s]\n", words.get(i), spaceAfterWords.get(i));
|
||||
|
||||
String word = words.get(i);
|
||||
String spaceAfterWord = spaceAfterWords.get(i);
|
||||
Boolean newlineAfterWord = newlinesAfterWords.get(i);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// if there's no space after the word, replace that with a single-space //
|
||||
// this happens if a word ended at the end of an input line //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if("".equals(spaceAfterWord) && !word.matches("^ +$"))
|
||||
{
|
||||
spaceAfterWord = " ";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
// start new output lines with first word //
|
||||
////////////////////////////////////////////
|
||||
if(outputLine == null)
|
||||
{
|
||||
outputLine = new StringBuilder().append(word);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean forcedNextLine = false;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// force the word onto the next line if we captured a leading-space with it //
|
||||
// this would come from an indented line. //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
if(word.startsWith(" "))
|
||||
{
|
||||
forcedNextLine = true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// add word to the output line, if it fits //
|
||||
/////////////////////////////////////////////
|
||||
if(outputLine.length() + word.length() <= length && !forcedNextLine)
|
||||
{
|
||||
outputLine.append(word);
|
||||
}
|
||||
else
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// if the word doesn't fit, then start a new output line with the next word //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
outputLines.add(outputLine.toString());
|
||||
outputLine = new StringBuilder().append(word);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// start a new line, if there's supposed to be one after this word //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
if(newlineAfterWord)
|
||||
{
|
||||
outputLines.add(outputLine.toString());
|
||||
outputLine = null;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// if there's room for the space(s) after this word, then add them //
|
||||
// else start a new line. this would be to prevent a word that had //
|
||||
// multiple spaces after it from losing them to a shorter next-word //
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
if(outputLine != null)
|
||||
{
|
||||
if(outputLine.length() + spaceAfterWord.length() <= length)
|
||||
{
|
||||
outputLine.append(spaceAfterWord);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputLines.add(outputLine.toString());
|
||||
outputLine = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(outputLine != null)
|
||||
{
|
||||
outputLines.add(outputLine.toString());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// trim any spaces away from end of output lines //
|
||||
///////////////////////////////////////////////////
|
||||
outputLines.replaceAll(s -> s.replaceFirst(" +$", ""));
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for maxLength
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setMaxLength(int maxLength)
|
||||
{
|
||||
this.maxLength = maxLength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for minLength
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setMinLength(int minLength)
|
||||
{
|
||||
this.minLength = minLength;
|
||||
}
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
package com.kingsrook.intellijcommentatorplugin.settings;
|
||||
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.ui.TitledSeparator;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBTextField;
|
||||
import com.intellij.util.ui.FormBuilder;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** UI for Commentator settings
|
||||
*******************************************************************************/
|
||||
public class CommentatorSettingsComponent
|
||||
{
|
||||
private final JPanel myMainPanel;
|
||||
private final JBTextField wrapCommentMaxWidthTextField = new JBTextField();
|
||||
private final JBTextField wrapCommentMinWidthTextField = new JBTextField();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public CommentatorSettingsComponent()
|
||||
{
|
||||
/* todo - this didn't work
|
||||
wrapCommentMaxWidthTextField.setInputVerifier(new InputVerifier()
|
||||
{
|
||||
@Override
|
||||
public boolean verify(JComponent input)
|
||||
{
|
||||
try
|
||||
{
|
||||
int value = Integer.parseInt(((JTextField) input).getText());
|
||||
return (value > 0 && value < 500);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
int indentSize = 20;
|
||||
myMainPanel = FormBuilder.createFormBuilder()
|
||||
|
||||
.addComponent(new TitledSeparator("Wrap Comment"))
|
||||
.addComponent(FormBuilder.createFormBuilder()
|
||||
.setFormLeftIndent(indentSize)
|
||||
.addLabeledComponent(new JBLabel("Max length: "), wrapCommentMaxWidthTextField, 1, false)
|
||||
.addLabeledComponent(new JBLabel("Min length: "), wrapCommentMinWidthTextField, 1, false)
|
||||
.getPanel())
|
||||
|
||||
.addComponent(new TitledSeparator("MyImporter"))
|
||||
.addComponent(FormBuilder.createFormBuilder()
|
||||
.setFormLeftIndent(indentSize)
|
||||
.addComponentFillVertically(createComponent(), 0)
|
||||
.getPanel())
|
||||
|
||||
.addComponentFillVertically(new JPanel(), 0)
|
||||
.getPanel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public JPanel getPanel()
|
||||
{
|
||||
return myMainPanel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public JComponent getPreferredFocusedComponent()
|
||||
{
|
||||
return wrapCommentMaxWidthTextField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getWrapCommentMaxWidthText()
|
||||
{
|
||||
return wrapCommentMaxWidthTextField.getText();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setWrapCommentMaxWidthText(String newText)
|
||||
{
|
||||
wrapCommentMaxWidthTextField.setText(newText);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getWrapCommentMinWidthText()
|
||||
{
|
||||
return wrapCommentMinWidthTextField.getText();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setWrapCommentMinWidthText(String newText)
|
||||
{
|
||||
wrapCommentMinWidthTextField.setText(newText);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private JPanel myMainComponent;
|
||||
private MyImporterAddEditDeleteListPanel importerPanel;
|
||||
|
||||
|
||||
|
||||
public JComponent createComponent()
|
||||
{
|
||||
if(myMainComponent == null)
|
||||
{
|
||||
myMainComponent = new JPanel(new BorderLayout());
|
||||
/*
|
||||
myCbUseSoftWrapsAtConsole = new JCheckBox(ApplicationBundle.message("checkbox.use.soft.wraps.at.console"), false);
|
||||
myCommandsHistoryLimitField = new JTextField(4);
|
||||
myCbOverrideConsoleCycleBufferSize = new JCheckBox(ApplicationBundle.message("checkbox.override.console.cycle.buffer.size", String.valueOf(ConsoleBuffer.getLegacyCycleBufferSize() / 1024)), false);
|
||||
myCbOverrideConsoleCycleBufferSize.addChangeListener(e -> {
|
||||
myConsoleCycleBufferSizeField.setEnabled(myCbOverrideConsoleCycleBufferSize.isSelected());
|
||||
myConsoleBufferSizeWarningLabel.setVisible(myCbOverrideConsoleCycleBufferSize.isSelected());
|
||||
});
|
||||
myConsoleCycleBufferSizeField = new JTextField(4);
|
||||
myConsoleBufferSizeWarningLabel = new JLabel();
|
||||
myConsoleBufferSizeWarningLabel.setForeground(JBColor.red);
|
||||
myConsoleCycleBufferSizeField.getDocument().addDocumentListener(new DocumentAdapter()
|
||||
{
|
||||
@Override
|
||||
protected void textChanged(@NotNull DocumentEvent e)
|
||||
{
|
||||
updateWarningLabel();
|
||||
}
|
||||
});
|
||||
myEncodingComboBox = new ConsoleEncodingComboBox();
|
||||
|
||||
JPanel northPanel = new JPanel(new GridBagLayout());
|
||||
GridBag gridBag = new GridBag();
|
||||
gridBag.anchor(GridBagConstraints.WEST).setDefaultAnchor(GridBagConstraints.WEST);
|
||||
northPanel.add(myCbUseSoftWrapsAtConsole, gridBag.nextLine().next());
|
||||
northPanel.add(Box.createHorizontalGlue(), gridBag.next().coverLine());
|
||||
JLabel label = new JLabel(ApplicationBundle.message("editbox.console.history.limit"));
|
||||
label.setLabelFor(myCommandsHistoryLimitField);
|
||||
northPanel.add(label, gridBag.nextLine().next());
|
||||
northPanel.add(myCommandsHistoryLimitField, gridBag.next());
|
||||
if(ConsoleBuffer.useCycleBuffer())
|
||||
{
|
||||
northPanel.add(myCbOverrideConsoleCycleBufferSize, gridBag.nextLine().next());
|
||||
northPanel.add(myConsoleCycleBufferSizeField, gridBag.next());
|
||||
northPanel.add(new JLabel(ExecutionBundle.message("settings.console.kb")), gridBag.next());
|
||||
northPanel.add(Box.createHorizontalStrut(JBUIScale.scale(20)), gridBag.next());
|
||||
northPanel.add(myConsoleBufferSizeWarningLabel, gridBag.next());
|
||||
}
|
||||
northPanel.add(new JLabel(ApplicationBundle.message("combobox.console.default.encoding.label")), gridBag.nextLine().next());
|
||||
northPanel.add(myEncodingComboBox, gridBag.next().coverLine());
|
||||
if(!editFoldingsOnly())
|
||||
{
|
||||
JPanel wrapper = new JPanel(new BorderLayout());
|
||||
wrapper.add(northPanel, BorderLayout.WEST);
|
||||
myMainComponent.add(wrapper, BorderLayout.NORTH);
|
||||
}
|
||||
*/
|
||||
|
||||
Splitter splitter = new Splitter(true);
|
||||
myMainComponent.add(splitter, BorderLayout.CENTER);
|
||||
importerPanel = new MyImporterAddEditDeleteListPanel(ApplicationBundle.message("console.fold.console.lines"), ApplicationBundle.message("console.enter.substring.folded"));
|
||||
// myNegativePanel = new MyAddDeleteListPanel(ApplicationBundle.message("console.fold.exceptions"), ApplicationBundle.message("console.enter.substring.dont.fold"));
|
||||
splitter.setFirstComponent(importerPanel);
|
||||
// splitter.setSecondComponent(myNegativePanel);
|
||||
|
||||
// myPositivePanel.getEmptyText().setText(ApplicationBundle.message("console.fold.nothing"));
|
||||
// myNegativePanel.getEmptyText().setText(ApplicationBundle.message("console.no.exceptions"));
|
||||
}
|
||||
|
||||
return myMainComponent;
|
||||
}
|
||||
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.kingsrook.intellijcommentatorplugin.settings;
|
||||
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** platform bridge for settings.
|
||||
*******************************************************************************/
|
||||
public class CommentatorSettingsConfigurable implements Configurable
|
||||
{
|
||||
private CommentatorSettingsComponent mySettingsComponent;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public @NlsContexts.ConfigurableName String getDisplayName()
|
||||
{
|
||||
return "Kingsrook Commentator";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createComponent()
|
||||
{
|
||||
mySettingsComponent = new CommentatorSettingsComponent();
|
||||
return mySettingsComponent.getPanel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent()
|
||||
{
|
||||
return mySettingsComponent.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public boolean isModified()
|
||||
{
|
||||
CommentatorSettingsState settings = CommentatorSettingsState.getInstance();
|
||||
|
||||
boolean modified = false;
|
||||
modified |= !mySettingsComponent.getWrapCommentMaxWidthText().equals(String.valueOf(settings.wrapCommentMaxWidth));
|
||||
modified |= !mySettingsComponent.getWrapCommentMinWidthText().equals(String.valueOf(settings.wrapCommentMinWidth));
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void apply() throws ConfigurationException
|
||||
{
|
||||
CommentatorSettingsState settings = CommentatorSettingsState.getInstance();
|
||||
settings.wrapCommentMaxWidth = Integer.parseInt(mySettingsComponent.getWrapCommentMaxWidthText());
|
||||
settings.wrapCommentMinWidth = Integer.parseInt(mySettingsComponent.getWrapCommentMinWidthText());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
CommentatorSettingsState settings = CommentatorSettingsState.getInstance();
|
||||
mySettingsComponent.setWrapCommentMaxWidthText(String.valueOf(settings.wrapCommentMaxWidth));
|
||||
mySettingsComponent.setWrapCommentMinWidthText(String.valueOf(settings.wrapCommentMinWidth));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void disposeUIResources()
|
||||
{
|
||||
mySettingsComponent = null;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.kingsrook.intellijcommentatorplugin.settings;
|
||||
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** State / model - for commentator settings
|
||||
*******************************************************************************/
|
||||
@State(
|
||||
name = "com.kingsrook.intellijcommentatorplugin.settings.CommentatorSettingsState",
|
||||
storages = @Storage("KingsrookCommentatorPlugin.xml")
|
||||
)
|
||||
public class CommentatorSettingsState implements PersistentStateComponent<CommentatorSettingsState>
|
||||
{
|
||||
public int wrapCommentMaxWidth = 96;
|
||||
public int wrapCommentMinWidth = 56;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static CommentatorSettingsState getInstance()
|
||||
{
|
||||
return ApplicationManager.getApplication().getService(CommentatorSettingsState.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public @Nullable CommentatorSettingsState getState()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void loadState(@NotNull CommentatorSettingsState state)
|
||||
{
|
||||
XmlSerializerUtil.copyBean(state, this);
|
||||
}
|
||||
|
||||
}
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
package com.kingsrook.intellijcommentatorplugin.settings;
|
||||
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import com.intellij.execution.ExecutionBundle;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.DialogWrapperPeer;
|
||||
import com.intellij.openapi.ui.InputValidator;
|
||||
import com.intellij.openapi.ui.InputValidatorEx;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.MultiLineLabelUI;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.AddEditDeleteListPanel;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
import com.intellij.util.ui.UI;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import static com.intellij.openapi.ui.Messages.getCancelButton;
|
||||
import static com.intellij.openapi.ui.Messages.getOkButton;
|
||||
import static com.intellij.openapi.ui.Messages.showTwoStepConfirmationDialog;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
class MyImporterAddEditDeleteListPanel extends AddEditDeleteListPanel<Pair<String, String>>
|
||||
{
|
||||
private final String myQuery;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
MyImporterAddEditDeleteListPanel(String title, String query)
|
||||
{
|
||||
super(title, new ArrayList<>());
|
||||
myQuery = query;
|
||||
// todo? ListSpeedSearch.installOn(myList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
protected @Nullable Pair<String, String> findItemToAdd()
|
||||
{
|
||||
return showEditDialog(new Pair<>("", ""));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private @Nullable Pair<String, String> showEditDialog(final Pair<String, String> initialValue)
|
||||
{
|
||||
InputValidatorEx inputValidatorEx = new InputValidatorEx()
|
||||
{
|
||||
@Override
|
||||
public @NlsContexts.DetailedDescription @Nullable String getErrorText(@NonNls String inputString)
|
||||
{
|
||||
return "Error?" ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkInput(String inputString)
|
||||
{
|
||||
return !StringUtil.isEmpty(inputString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canClose(String inputString)
|
||||
{
|
||||
return !StringUtil.isEmpty(inputString);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// String first = Messages.showInputDialog(this, myQuery, ExecutionBundle.message("dialog.title.folding.pattern"), Messages.getQuestionIcon(), initialValue.getFirst(), inputValidatorEx);
|
||||
// String second = Messages.showInputDialog(this, myQuery, ExecutionBundle.message("dialog.title.folding.pattern"), Messages.getQuestionIcon(), initialValue.getSecond(), inputValidatorEx);
|
||||
|
||||
Messages.InputDialog dialog = new MyImporterInputDialog(this, myQuery, "Import Pair", Messages.getQuestionIcon(), initialValue, inputValidatorEx);
|
||||
/*
|
||||
|
||||
final JTextComponent field = dialog.getTextField();
|
||||
if (selection != null) {
|
||||
// set custom selection
|
||||
field.select(selection.getStartOffset(), selection.getEndOffset());
|
||||
field.putClientProperty(DialogWrapperPeer.HAVE_INITIAL_SELECTION, true);
|
||||
}
|
||||
*/
|
||||
|
||||
dialog.show();
|
||||
String first = dialog.getInputString();
|
||||
String second = "NYditty" ;
|
||||
|
||||
return new Pair<>(first, second);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class MyImporterInputDialog extends Messages.InputDialog
|
||||
{
|
||||
public static final int INPUT_DIALOG_COLUMNS = 30;
|
||||
private InputValidator myValidator; // todo!!
|
||||
|
||||
// protected JTextComponent myField;
|
||||
protected JTextComponent field0;
|
||||
protected JTextComponent field1;
|
||||
private String myComment;
|
||||
|
||||
|
||||
|
||||
public MyImporterInputDialog(@NotNull Component parent, @NlsContexts.DialogMessage String message, @NlsContexts.DialogTitle String title, @Nullable Icon icon, @Nullable Pair<String, String> initialValue, @Nullable InputValidator validator)
|
||||
{
|
||||
super(parent, message, title, icon, "uh", validator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void enableOkAction()
|
||||
{
|
||||
getOKAction().setEnabled(myValidator == null || myValidator.checkInput(field0.getText().trim()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected Action @NotNull [] createActions()
|
||||
{
|
||||
final Action[] actions = new Action[myOptions.length];
|
||||
for(int i = 0; i < myOptions.length; i++)
|
||||
{
|
||||
String option = myOptions[i];
|
||||
final int exitCode = i;
|
||||
if(i == 0)
|
||||
{ // "OK" is default button. It has index 0.
|
||||
actions[0] = getOKAction();
|
||||
actions[0].putValue(DialogWrapper.DEFAULT_ACTION, Boolean.TRUE);
|
||||
myField.getDocument().addDocumentListener(new DocumentAdapter()
|
||||
{
|
||||
@Override
|
||||
public void textChanged(@NotNull DocumentEvent event)
|
||||
{
|
||||
final String text = myField.getText().trim();
|
||||
actions[exitCode].setEnabled(myValidator == null || myValidator.checkInput(text));
|
||||
if(myValidator instanceof InputValidatorEx)
|
||||
{
|
||||
setErrorText(((InputValidatorEx) myValidator).getErrorText(text), myField);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
actions[i] = new AbstractAction(option)
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
close(exitCode);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void doOKAction()
|
||||
{
|
||||
String inputString = myField.getText().trim();
|
||||
if(myValidator == null ||
|
||||
myValidator.checkInput(inputString) &&
|
||||
myValidator.canClose(inputString))
|
||||
{
|
||||
close(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected JComponent createNorthPanel()
|
||||
{
|
||||
JPanel panel = createIconPanel();
|
||||
|
||||
JPanel messagePanel = createMessagePanel();
|
||||
panel.add(messagePanel, BorderLayout.CENTER);
|
||||
|
||||
if(myComment != null)
|
||||
{
|
||||
return UI.PanelFactory.panel(panel).withComment(myComment).createPanel();
|
||||
}
|
||||
else
|
||||
{
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected @NotNull JPanel createMessagePanel()
|
||||
{
|
||||
JPanel messagePanel = new JPanel(new BorderLayout());
|
||||
if(myMessage != null)
|
||||
{
|
||||
JComponent textComponent = createTextComponent();
|
||||
messagePanel.add(textComponent, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
myField = createTextFieldComponent();
|
||||
messagePanel.add(createScrollableTextComponent(), BorderLayout.SOUTH);
|
||||
|
||||
return messagePanel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected JComponent createScrollableTextComponent()
|
||||
{
|
||||
return myField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected JComponent createTextComponent()
|
||||
{
|
||||
JComponent textComponent;
|
||||
if(BasicHTML.isHTMLString(myMessage))
|
||||
{
|
||||
textComponent = createMessageComponent(myMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
JLabel textLabel = new JLabel(myMessage);
|
||||
textLabel.setUI(new MultiLineLabelUI());
|
||||
textComponent = textLabel;
|
||||
}
|
||||
textComponent.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 20));
|
||||
return textComponent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public JTextComponent getTextField()
|
||||
{
|
||||
return myField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected JTextComponent createTextFieldComponent()
|
||||
{
|
||||
JTextField field = new JTextField(INPUT_DIALOG_COLUMNS);
|
||||
field.setMargin(JBInsets.create(0, 5));
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent()
|
||||
{
|
||||
return myField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public @Nullable @NlsSafe String getInputString()
|
||||
{
|
||||
return getExitCode() == 0 ? myField.getText().trim() : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
void resetFrom(List<String> patterns)
|
||||
{
|
||||
myListModel.clear();
|
||||
patterns.stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(myListModel::addElement);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void applyTo(List<? super String> patterns)
|
||||
{
|
||||
patterns.clear();
|
||||
for(Object o : getListItems())
|
||||
{
|
||||
patterns.add((String) o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void addRule(String rule)
|
||||
{
|
||||
addElement(rule);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected Pair<String, String> editSelectedItem(Pair<String, String> item)
|
||||
{
|
||||
return showEditDialog(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin.utils;
|
||||
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class CommentUtils
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String getCommentChar(Document document)
|
||||
{
|
||||
String commentChar = "/";
|
||||
try
|
||||
{
|
||||
VirtualFile currentFile = FileDocumentManager.getInstance().getFile(document);
|
||||
if(currentFile != null)
|
||||
{
|
||||
String fileName = currentFile.getPath();
|
||||
if(fileName.endsWith(".sh") || fileName.endsWith(".vtl") || fileName.endsWith(".vm") || fileName.endsWith(".pl"))
|
||||
{
|
||||
commentChar = "#";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// leave default
|
||||
}
|
||||
return commentChar;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static int getSelectionEndLine(SelectionModel selectionModel, Document document, String commentChar)
|
||||
{
|
||||
int selectionEndOffset = selectionModel.getSelectionEnd();
|
||||
int selectionEndLine = document.getLineNumber(selectionEndOffset);
|
||||
while(selectionEndLine < document.getLineNumber(document.getTextLength()) - 1)
|
||||
{
|
||||
TextRange lineBelowSelectionTextRange = new TextRange(document.getLineStartOffset(selectionEndLine + 1), document.getLineEndOffset(selectionEndLine + 1));
|
||||
String lineBelow = document.getText(lineBelowSelectionTextRange);
|
||||
|
||||
if(lineBelow.matches("^ *" + commentChar + commentChar + ".*"))
|
||||
{
|
||||
selectionEndLine++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return selectionEndLine;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static int getSelectionStartLine(SelectionModel selectionModel, Document document, String commentChar)
|
||||
{
|
||||
int selectionStartOffset = selectionModel.getSelectionStart();
|
||||
int selectionStartLine = document.getLineNumber(selectionStartOffset);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// expand the selection upward as long as more comment lines are found //
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
while(selectionStartLine > 1)
|
||||
{
|
||||
TextRange lineAboveSelectionTextRange = new TextRange(document.getLineStartOffset(selectionStartLine - 1), document.getLineEndOffset(selectionStartLine - 1));
|
||||
String lineAbove = document.getText(lineAboveSelectionTextRange);
|
||||
|
||||
if(lineAbove.matches("^ *" + commentChar + commentChar + ".*"))
|
||||
{
|
||||
selectionStartLine--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return selectionStartLine;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -24,44 +24,160 @@
|
||||
<!-- Unique identifier of the plugin. It should be FQN. It cannot be changed between the plugin versions. -->
|
||||
<id>com.kingsrook.intellij-commentator-plugin</id>
|
||||
|
||||
<version>1.5.0</version>
|
||||
|
||||
<!-- Public plugin name should be written in Title Case.
|
||||
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-name -->
|
||||
<name>Kingsrook Commentator</name>
|
||||
|
||||
<!-- A displayed Vendor name or Organization ID displayed on the Plugins Page. -->
|
||||
<vendor email="support@kingsrook.com" url="https://www.kingsrook.com">Kingsrook</vendor>
|
||||
<vendor email="contact@kingsrook.com" url="https://www.kingsrook.com">Kingsrook</vendor>
|
||||
|
||||
<!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager.
|
||||
Simple HTML elements (text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag.
|
||||
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-description -->
|
||||
<description><![CDATA[
|
||||
IntelliJ plugin to provide code editing tools desired by the Kingsrook development team.
|
||||
<h2>Overview</h2>
|
||||
<p>The <b>Kingsrook Commentator</b> is a plugin to provide code editing tools desired by the Kingsrook development team.</p>
|
||||
<p>Specifically:</p>
|
||||
<ul>
|
||||
<li>Single-button to create a flower-box comment.</li>
|
||||
<li>Single-button to create a flower box comment.</li>
|
||||
<li>Smart-case substitutions (e.g., MyVar myVar s/my/your/ = YourVar yourVar).</li>
|
||||
<li>Write missing get/set/with methods for fields.</li>
|
||||
<li>Quickly do a URI decode on selected text.</li>
|
||||
<li>Auto-Import classes or methods that IntelliJ refuses to "just do".</li>
|
||||
<li>Auto-line-re-wrapping for flower box comments.</li>
|
||||
<li>Class/Method headers.</li>
|
||||
</ul>
|
||||
<p>Future plans may include:</p>
|
||||
<ul>
|
||||
<li>Auto-line-re-wrapping for flower-box comments.</li>
|
||||
<li>Class/Method headers.</li>
|
||||
<li>Language-aware and/or user-customizable comment-characters</li>
|
||||
<li>Smart-case substitutions (e.g., MyVar myVar s/my/your/ = YourVar yourVar).</li>
|
||||
<li>Conversion of words from say this_case or this-case to thisCase or ThisCase or THIS_CASE, etc</li>
|
||||
</ul>
|
||||
<h2>Usage</h2>
|
||||
|
||||
<h3>Single-button to create a flower box comment</h3>
|
||||
<p>The Kingsrook coding standard requires full Flower Box comments for all inline source documentation. However,
|
||||
these can be quite painful to "draw" by-hand. As such, the Commentator plugin provides a single button that
|
||||
can be pressed (that is, via keyboard shortcut or menu option) to convert one or more lines of text to a properly
|
||||
formatted Flower Box comment, like this:</p>
|
||||
<pre>
|
||||
//////////////////////////////////////////////////////////
|
||||
// This is a beautiful example of a flower box comment! //
|
||||
//////////////////////////////////////////////////////////
|
||||
</pre>
|
||||
<p>In addition, if you edit a comment (adding or removing words, even adding lines), you can reformat your Flower
|
||||
Box with the same action.</p>
|
||||
<p>To use this action to create (or update) a Flower Box comment:</p>
|
||||
<ul>
|
||||
<li>Place your cursor within a line of text that you want to convert into a flower box. You can have existing
|
||||
comment characters already in the line (e.g., it's common to write the line with a leading <code>//</code>, to
|
||||
prevent the line from being falsely-flagged as a syntax error). Alternatively, you can select (portions) of one
|
||||
or more lines, if you are making a multi-line comment.</li>
|
||||
<li>To trigger the action, just hit its hotkey / keyboard shortcut. By default, this is <b>F6</b> (but of course you can
|
||||
customize that under Preferences, Keymap).</li>
|
||||
<li>Alternatively, you can select it from the <b>Code</b> menu: <b>Create Flower Box Comment</b></li>
|
||||
</ul>
|
||||
<p><i>Note that, at this time, only <code>/</code> (slash) is supported as a comment character. Future versions of
|
||||
this plugin may include language-specific comment characters, and/or preferences to customize the character used.</i></p>
|
||||
|
||||
<h3>Smart-case substitutions (e.g., MyVar myVar s/my/your/ = YourVar yourVar).</h3>
|
||||
<p>A super-common use case (for me, at least) is to want to substitute one word for another, in a camel-case sensitive
|
||||
manner, such that occurrences of the word that start with either an upper or
|
||||
lowercase letter get replaced by the replacement, preserving the case of the initial letter. (I use the word "substitute"
|
||||
as a reference to VI's <code>:s</code> command, though I suppose Find and Replace is the more common GUI terminology for
|
||||
the concept...)</p>
|
||||
<p>The most common example of this in Java development, is in copying & pasting getter & setter methods (and these days,
|
||||
we tend to also write fluent setters (e.g., <code>withVar</code>)).</p>
|
||||
<p>For example, if you have these methods:<p>
|
||||
<pre>public String getCity()
|
||||
{
|
||||
return(city);
|
||||
}
|
||||
|
||||
public void setCity(String city)
|
||||
{
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public Address withCity(String city)
|
||||
{
|
||||
this.city = city;
|
||||
return (this);
|
||||
}
|
||||
</pre>
|
||||
<p>And you want to copy & paste them for a new field, <code>state</code>. By using <b>SmartSubstitute</b>, your steps to do this
|
||||
would be:</p>
|
||||
<ul>
|
||||
<li>copy the code</li>
|
||||
<li>paste it</li>
|
||||
<li>select the pasted code</li>
|
||||
<li>open <b>SmartSubstitute</b> (from the Edit → Find menu)</li>
|
||||
<li>tell it to replace <u>city</u> with <u>state</u></li>
|
||||
</ul>
|
||||
<p>The result you'll get is, in the selected code, both the literal values you entered for find and replace will be substituted
|
||||
(e.g., "city" for "state", for the variable and field names, that start with lower case letters), and also, automatically
|
||||
<u>City</u> will be replaced with <u>State</u> (e.g., in the method names, for the inner word starting with an upper case letter)
|
||||
- just like you would have wanted!</p>
|
||||
|
||||
<h3>GetSetWith method generation</h3>
|
||||
<p>If you add new fields to a class - you can quickly & easily generate getter, setter, and fluent-setter ("wither") methods,
|
||||
by selecting the lines with the fields, and invoking the <b>GetSetWith</b> command. It attempts to be smart and not re-generate
|
||||
any that already exist. Note, it doesn't quite work well for inner-classes.</p>
|
||||
]]></description>
|
||||
|
||||
<!-- Product and plugin compatibility requirements.
|
||||
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html -->
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
<depends>com.intellij.modules.java</depends>
|
||||
|
||||
<idea-version since-build="222.3345.118"/>
|
||||
|
||||
<!-- Extension points defined by the plugin.
|
||||
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-extension-points.html -->
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
|
||||
<notificationGroup id="Kingsrook Commentator Notifications" displayType="BALLOON"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<applicationService serviceImplementation="com.kingsrook.intellijcommentatorplugin.settings.CommentatorSettingsState"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<applicationConfigurable
|
||||
parentId="tools"
|
||||
instance="com.kingsrook.intellijcommentatorplugin.settings.CommentatorSettingsConfigurable"
|
||||
id="org.intellij.sdk.settings.AppSettingsConfigurable"
|
||||
displayName="Kingsrook Commentator"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.CreateBoxCommentAction" class="com.kingsrook.intellijcommentatorplugin.CreateBoxCommentAction" text="Create Box Comment" description="Creates a Box Comment (Flowerbox) out of the current line">
|
||||
<add-to-group group-id="CodeMenu" anchor="first"/>
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="F6"/>
|
||||
</action>
|
||||
<group id="com.kingsrook.intellijcommentatorplugin.KingsrookCommentatorGroup" text="Kingsrook Commentator" popup="true" icon="/META-INF/pluginMenuIcon.svg">
|
||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.CreateBoxCommentAction" class="com.kingsrook.intellijcommentatorplugin.CreateBoxCommentAction" text="Create Flower Box Comment" description="Creates a Box Comment (Flowerbox) out of the current line">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="F6"/>
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.WrapCommentAction" class="com.kingsrook.intellijcommentatorplugin.WrapCommentAction" text="Wrap Flower Box Comment" description="Wrap a Box Comment (Flowerbox) that got too long">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl F5"/>
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.HeaderCommentAction" class="com.kingsrook.intellijcommentatorplugin.HeaderCommentAction" text="Write Header Comment" description="Write a stub of a method/class/etc header comment">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt m"/>
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.CaseChangerAction" class="com.kingsrook.intellijcommentatorplugin.CaseChangerAction" text="Case Changer" description="Change the capitalization style of the word under the cursor">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="alt C"/>
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.SSAction" class="com.kingsrook.intellijcommentatorplugin.SSAction" text="SS - SmartSubstitution" description="Substitution action that is Smart w/r/t capitalization">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt S"/>
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.GetSetWithAction" class="com.kingsrook.intellijcommentatorplugin.GetSetWithAction" text="Get, Set, With" description="Write getX, setX, withX methods">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt w"/>
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.MyImporterAction" class="com.kingsrook.intellijcommentatorplugin.MyImporterAction" text="My Importer" description="Import things the way I want you to.">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt i"/>
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.URIDecodeAction" class="com.kingsrook.intellijcommentatorplugin.URIDecodeAction" text="URI Decode" description="Do a URI Decode on the selected text.">
|
||||
</action>
|
||||
<action id="com.kingsrook.intellijcommentatorplugin.StubSetterCallsAction" class="com.kingsrook.intellijcommentatorplugin.StubSetterCallsAction" text="Stub Setter Calls" description="Write a stub of calls to all setters on an object">
|
||||
</action>
|
||||
</group>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,752 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!--
|
||||
- Kingsrook IntelliJ Commentator Plugin
|
||||
- Copyright (C) 2022. Kingsrook, LLC
|
||||
- 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
- contact@kingsrook.com
|
||||
- https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 10.583333 10.583333"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.1.1 (c3084ef, 2021-09-22)"
|
||||
sodipodi:docname="kingsrook-plugin.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="in"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
width="16px"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="-51.125"
|
||||
inkscape:cy="-15.125"
|
||||
inkscape:window-width="2530"
|
||||
inkscape:window-height="1343"
|
||||
inkscape:window-x="3023"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2">
|
||||
<style
|
||||
id="style1055">.cls-1{fill:#202020;}</style>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<image
|
||||
width="9.0619745"
|
||||
height="9.0619745"
|
||||
preserveAspectRatio="none"
|
||||
xlink:href="data:image/png;base64,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
|
||||
AMYCnBe/35gBSm0AAAAASUVORK5CYII=
|
||||
"
|
||||
id="image1177"
|
||||
x="0.33073115"
|
||||
y="0.3307305" />
|
||||
<g
|
||||
id="g1135"
|
||||
transform="matrix(0.01095221,0,0,0.01095221,1.2684344,4.3227592)">
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 149.84,473.61 c 7.43,3.67 -2.32,-4.73 5.26,1.74 a 4.33,4.33 0 0 1 -5.26,-1.74 z"
|
||||
id="path1059" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 210.35,456.12 c 17.42,-22.12 52.59,-30.69 78,-45.13 3.21,-1.2 0.62,4.6 7.64,1.65 25,-15.07 71.35,-17.28 104.83,-10.82 l -2.09,1.32 c 6.35,1.05 14.46,-2.19 21.3,-1.06 0,0.86 -2.31,1 -0.84,2.36 2,-2.45 12.44,-0.09 15.62,-1.75 2.56,1.26 2,3.44 5.25,5.16 l 4.31,-2.23 c 12,-5 26.16,4.91 41.35,5.71 -0.89,0.48 -2.47,0.62 -1.49,1.57 24.58,1.48 52.94,13.08 78.22,22.88 -1.42,0.49 -3.11,1.8 -2.19,3.55 2.51,-2.24 10.48,0.52 17.29,3.21 1.39,4.43 12.47,3.13 19.14,8.93 l -1,0.24 c 7.16,0.3 7.16,6.32 13.64,5.56 l 2.1,4.3 c 5.53,-1.31 5.92,6.77 10,2.16 l -0.55,-0.74 c 2.83,-3.57 6.23,-2.45 8.84,-6.44 l 0.65,0.08 c 6.65,-7.85 12.2,-11.29 9.48,-13.28 4.58,-0.92 -5.76,8.52 1.15,6.92 18.22,-30.67 46.84,-53.65 68.41,-81 3.61,-2.19 5.55,-3.9 7.17,-3.75 1.67,-3.16 7.79,-10.73 8.37,-14.35 -0.69,1 2.84,-0.64 4.13,-2 5,-4.2 1.3,-7.9 6.88,-12.43 -1,2.78 -0.68,4.23 0.94,4.31 1.53,-6.42 6.83,-12.45 10.47,-18.61 -0.21,1.23 -1,2.8 0.06,3.28 2.29,-8.05 9.19,-10.78 11.78,-17.36 l 0.07,3.25 c 8.65,-7.15 -1.42,-5.17 5.51,-11.77 -0.87,2.2 0.25,2.05 0.65,2.88 -0.44,-6.94 18.52,-25.05 9.88,-22.44 l 0.86,-0.34 c -7.18,-6.26 -13.7,-14 -22.73,-19.54 -2.35,-3.12 4.29,-3.09 -4.12,-8.91 -2.16,3.16 -14.67,-8.86 -12.59,-1.55 -7.14,-7.64 -14.6,-7.94 -18.7,-2 2.09,-3.14 -6.63,-1.67 -0.84,-5.78 l -6,1.45 c -0.69,-2 5,-3.26 2.24,-3.83 -3.27,2.53 -9.78,11.34 -12.23,13.5 -2.64,6.82 -2.65,14.44 -8.39,23.42 1.6,-5.05 -5.36,-0.25 -4,-3.46 -5.35,6.21 8.8,9.91 -12,18.09 -3,-2 1.31,-3.05 -3.5,-5.32 -0.43,1 -2.66,0.2 -4.45,0 -0.8,-1.21 -12.61,-8.19 -11.43,-12.37 -0.35,-2.21 5.19,2.86 2.87,-0.69 -4,-6.37 -9.3,2.35 -8.9,-12.36 h 0.56 c 2,-4 2.53,-12.81 -1.12,-9 -1.09,2.86 2.67,-0.32 0.1,3.6 -1.22,-3.69 0.64,-11.23 2.75,-17.55 -0.13,2.36 1,2.45 1.78,3.67 -0.14,-9.49 2,-18.79 3.91,-28.68 -1.77,-0.77 2.11,4.65 0.68,5.72 3.31,-5.64 4.54,-12.2 5.83,-18.47 l 1,-4.61 0.27,-1.13 c 5.61,21.35 1,5.61 2.06,10.24 l -1.7,-1.11 a 19.34,19.34 0 0 1 -5.52,-5.48 c 1.5,0.65 -0.87,2.73 -0.65,2.23 -4.41,-3.27 -2.45,-5.89 -6.44,-6.64 0.46,-1.59 -4.54,-1.7 -8.2,-3 -2.3,0.15 -0.55,-1.18 2.56,0.21 -5.3,-1.62 -26.17,-7.83 -38,-13.32 -0.11,1.12 -8.57,1.39 -11.43,0.71 l 1.76,-2.16 c -2.25,-2.12 -9.68,-2.21 -9.66,-4.43 -6.88,1.29 24.38,3.63 15.45,3.77 -1.54,-2.85 -12.63,0.9 -9.94,-2 -5.83,-1.44 -12,0 -17.16,-3.37 1.52,0.74 5.48,-2.44 0.69,-3.25 -8.48,-1.29 -2.63,0.64 -9.57,0.24 l -4.42,0.27 c -0.36,1.18 -2.09,0.84 -3.47,0.58 h -0.08 l 13,-8.82 v 0 0 0.13 l -0.06,0.25 -0.11,0.47 v 0.65 c 0.09,0.28 0.46,0.23 1.32,-0.39 -2.23,0.55 -1.87,12.63 -5.6,10.78 l -2.82,-2 c -0.7,3.72 1.78,6.83 2.43,10 -0.4,0.42 -1.27,1.22 -1.73,0.92 4.63,1.78 -2.58,8.66 0,13.94 -3.58,7.27 -5,19.51 -8.92,22.4 v 2.42 0 l -16.6,6.88 H 544 543.55 l -0.91,-0.06 -3.4,-0.38 c -2,-0.54 -4.37,-1 -7.3,-2.05 1.27,-0.21 2.89,0 3.52,-1 -3.36,-2.18 -4.66,-1.14 -8.14,-1.11 1.12,-0.84 -7.53,-3.74 -12,-6 -5.89,1.17 -4,4 -4.66,5.55 -5.12,-5.15 -16.13,2.86 -22.86,-1.13 2,-0.87 8.42,-2.64 3.5,-3.77 -5.62,-4.59 -10.74,4.08 -19.24,2.65 l 2.43,3.78 -1.59,-0.45 h -0.44 -0.2 c 3.07,2.77 -26.71,-24.14 -14.1,-12.75 v 0 0 -0.23 -1 l -0.43,-4.15 c -0.35,-2.63 -0.53,-4.66 1.52,-4.21 -1.44,-2.95 1.35,-10.4 -2.6,-9.39 3.31,-14.51 -2.8,-34.93 2.62,-42.58 -1.74,-3.74 -0.09,-1.64 -1.15,0.31 -4.82,-5 1.17,0.54 -0.75,0.06 a 1.67,1.67 0 0 0 -2,-1.13 c 2.53,2.44 3.38,2.2 4.75,-0.87 -2.94,-3.84 -8.05,4 -18.43,1.14 0.71,-1.5 0,-2.34 -3.69,-2.4 l -7,2.09 c -8,-1.21 -4.33,-4 -4.33,-6.77 -4.38,0.14 -9.75,-0.18 -11.82,1.74 l -5.22,-3.63 c 3.82,2.63 -3.67,1.5 -5.75,2.16 l 2.08,-0.63 c -0.77,-1.19 -5.91,-0.58 -8.5,-0.29 0.6,1.72 5.78,2.52 8.59,3.08 -2.27,1.16 -5.76,0.8 -8.75,2.17 1,-2.68 -7.14,-2 -10.63,-2.3 -4,-0.59 -4.51,2.42 -5.68,2.34 -0.12,-1.41 -6.49,-0.18 -3.42,-2.18 1.37,-0.46 3.13,1.34 5.38,0.09 -2.62,-1 -2.38,-3.48 -7.81,-1.63 -2.06,0.7 -1.66,2 -1.85,3 l -0.83,1 -0.23,0.05 v 0 a 6.62,6.62 0 0 0 1,-0.06 c 0.66,-0.21 0,0.33 3.83,-1 1,-0.93 3.69,-0.29 7.58,-7.7 3.77,-10.43 -5,-17.4 -6.11,-17.28 -4,-1.91 -4,-1.36 -4.79,-1.64 a 16.79,16.79 0 0 0 -1.69,-0.15 c -0.62,0 0.23,0.08 0.3,0.13 a 19.77,19.77 0 0 1 4.11,1.38 c 3.42,1.22 8.64,6.2 9.91,11.32 -2.12,-5.22 -6.6,-8.45 -9.46,-9.3 l -4,-0.83 -0.88,-0.05 c 0.08,0 -0.85,0 0.38,0 l 1,0.11 c -1.62,4.09 6,-9.85 8,16.78 -12.73,10.24 -6.43,3.45 -8.69,5.54 h -0.58 v -0.05 l 0.48,-0.37 -0.42,-0.08 h -0.1 0.25 0.53 a 8.82,8.82 0 0 0 1.2,-0.2 10,10 0 0 0 3.06,-1.22 c 3.38,2.66 8.2,-16 1,-17.69 -10.13,-4.18 -4.27,-1.27 -6.23,-2.16 -0.27,0 0.38,0.15 0.54,0.24 l 3.71,1.7 a 15.44,15.44 0 0 1 6.32,7.19 c 1.85,5.34 0.37,4.14 0.7,6.5 l 2.48,0.07 c -0.52,1.33 -0.81,0.49 -1.08,1.09 3.15,3.07 1.09,12.85 3.94,14.63 0.25,4.14 -2.11,8.18 -2.59,11.87 l -0.17,-0.72 c -1.68,4.42 -1.22,10.37 0.09,14.24 l -0.52,-0.24 c -0.4,2.42 -0.51,8.18 0.59,11.35 -2.48,5.91 -9.44,1.08 -7.07,8.13 -0.59,6.13 3.39,10.19 5.25,7.87 l -0.5,2.1 -0.21,1.06 v 0.06 0 c -5,5.38 11.31,-12 -11.32,12.08 h -0.13 -0.26 l -0.53,0.08 -4.22,0.78 -8.46,2.08 c -5.63,1.38 -11.21,2.48 -16.59,1.55 -1.38,1.28 -0.28,1.7 -3.39,2.89 -8,1 -16.31,3.32 -24.26,5.07 l -1.49Line truncated
|
||||
id="path1061" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 141.18,468.75 c -0.57,-2.47 -5,-6.33 0.21,-6 -0.39,1.76 1.14,4.93 -0.21,6 z"
|
||||
id="path1063" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 62.55,344.77 c -0.58,0 -0.25,-2.32 -0.18,-2.89 0.91,1.69 3.05,2.7 2.81,4.49 -0.91,-1.74 -1.59,-1.11 -2.63,-1.6 z"
|
||||
id="path1065" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 46.68,308.13 c 1.68,-0.16 6.67,7 9,11.53 z"
|
||||
id="path1067" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M 27.33,266.2 C 8.56,255.36 -5.19,271.1 1.5,265 c 1.23,-1.19 9.85,-6.6 20.79,-3.27 11.31,4.86 5.74,3.34 9.93,6.14 -0.02,1.13 -2.86,-1.03 -4.89,-1.67 z"
|
||||
id="path1069" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 7.86,267.37 c 1.79,-2.56 17.41,-0.7 20.32,8.59 2.57,6.92 1.11,8.7 1.12,10.2 a 14,14 0 0 1 -1.25,3.57 l -0.36,1 -0.77,1.46 1.21,-0.85 2.4,-0.93 c -0.6,-0.38 -1.42,1 -2.3,2.18 -0.88,1.18 1.07,-1.44 1.12,-2.7 0.07,-1.59 1.84,-1.05 1.06,-10.33 0.61,-5.23 -10,-15.39 -16.58,-14 -5.92,0.17 -7.29,1.64 -8.51,2.13 -2.53,1.95 -3.91,2.46 2.54,-0.32 z"
|
||||
id="path1071" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 80.25,241 c 1,-0.94 3,-4.33 4.88,-3.45 -1.77,-0.35 -4.32,6.01 -4.88,3.45 z"
|
||||
id="path1073" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 84.63,239.61 c 0.72,0.85 0.85,1.37 2.07,1.94 1,1.95 -1.39,1.31 -2.71,0.25 z"
|
||||
id="path1075" />
|
||||
<polygon
|
||||
class="cls-1"
|
||||
points="476.86,221.2 477.27,219.56 480.59,220.07 "
|
||||
id="polygon1077" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 652,233 c -0.33,4.11 -2.32,2.15 -2.76,2.71 0.95,-3.48 1.4,1.9 2.76,-2.71 z"
|
||||
id="path1079" />
|
||||
<polygon
|
||||
class="cls-1"
|
||||
points="746.86,255.4 749.25,253.06 747.83,256.11 "
|
||||
id="polygon1081" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 82.9,417.15 c -1.59,2 2.73,1.52 -0.59,2 -0.5,-1.29 -0.65,-2.39 0.59,-2 z"
|
||||
id="path1083" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 678.23,395.11 c -11.44,1.33 -13.26,-12 -23.29,-13 -1,-0.31 3.07,-3.48 0.61,-3.93 -10.7,0.49 -18,-10.62 -23.85,-20.08 l 1.25,-0.77 c -1.13,-1.8 -5.45,0.59 -6.83,-1 0.45,-0.73 1.21,-0.69 1.46,-1.95 -1.84,1.94 -3.75,-0.9 -5.51,0.29 -0.14,-1.28 1,-3 0.74,-4.53 l -2.54,1.93 c -6.37,4.43 -6.29,-4.64 -11.95,-3.56 0.52,-0.5 1.17,-0.77 1.2,-1.52 -8.31,0.55 -15.6,-4.11 -23.17,-6.22 a 7.7,7.7 0 0 0 1.91,-3.68 c -1.72,2.69 -4.11,2.16 -6.3,2 0.46,-3.29 -4.48,1.31 -6,-1.24 l 0.47,-0.56 c -3,2.4 -1.69,-2.81 -4.61,0.35 l -0.06,-2.77 c -2.47,3.89 -1.49,-3.17 -3.74,-1.6 l -0.31,0.87 c -1.69,0.49 -1.51,-1.9 -3,-1.69 l 0.08,-0.53 c -3.22,-0.07 -4,-3.1 -5.14,0.24 0,-3.07 3.17,-0.08 3.11,-4.59 -10.68,-0.16 -20.23,-3.75 -29.82,-6.82 -0.72,-1.64 -1.32,-2.23 -1.2,-3.59 -1.18,0.46 -3.89,-0.28 -5.24,1.26 0.35,0 -0.17,-1.91 -0.65,-2.21 -1.45,-1.73 -2.9,3.29 -4.47,1.27 a 3.81,3.81 0 0 0 1.6,-3.11 c -2.33,2.27 -4.46,1.29 -6.63,1.68 0.44,-0.5 1,-0.73 1.18,-1.83 -2.86,2.52 -3.81,-1.62 -6.13,-0.15 l 1.13,-1.82 c -2.54,-3.18 -1.79,3.94 -4.12,1.89 0.78,-0.52 0.71,-1.33 1,-2.12 -3.23,3.17 -7,1.31 -9.71,2.12 l 0.25,-0.81 c -2.77,0 -5.41,-1.63 -8.63,-0.53 -0.94,-1.08 1.13,-4.87 -1.86,-4.61 -0.52,4.07 -5.12,0.83 -4.09,5.71 -2.3,-1.18 -6,-3 -7.82,-1.78 1.29,-1.43 -0.61,-5.09 1.49,-5.22 l -1.27,-2.64 c 0.44,-1.64 1.55,0.73 1.31,-1.42 -1.07,0.07 -4.29,1.37 -5.15,0.61 -2.21,2.3 -4.42,6.8 -7.52,7 1.59,-1.44 -0.43,-4.58 0.63,-5.18 l -5,7.38 c -1,0.09 0,-3.24 -1.52,-2.32 0,1.08 -0.7,1.69 -1.2,2.53 -0.36,-0.6 -4.29,0.76 -4.49,-3.28 -0.36,-1.58 1.72,-0.77 0.67,-2.26 -1.9,0 -2.07,1.35 -4,1.34 v -0.54 c -1.24,-0.64 -3.77,1.58 -2.52,3.87 0.86,0.14 -0.22,-2.44 1,-1.22 -1,2.31 -3.19,2.88 -5.06,2.85 0.66,-0.61 0.62,-1.7 0.93,-2.83 -2.66,3.08 -5.34,4 -8.15,5.21 -0.08,1.92 1.11,-3.46 1.5,-2.43 -3.58,-2.85 -7.45,3.51 -10.43,-0.24 0.48,-0.34 0.27,2.73 0.23,2.19 -1.72,-0.2 -1.67,-3 -2.8,-1.93 -0.12,-1.63 -1.42,0.56 -2.56,1.08 -0.58,1.19 -0.32,-0.79 0.69,-1 -1.61,1.4 -8,4.07 -11.8,1.78 0.11,1.07 -2.11,4 -3,3.9 l 0.2,-2.53 c -0.85,-1.53 -2.85,0.43 -3.11,-1.74 -1.68,3.1 6.94,-3 4.57,-0.48 -0.75,-2.11 -3.25,4.12 -2.9,0.68 -1.72,0.24 -3.21,3.2 -5,1 0.5,0.36 1.18,-3.61 -0.21,-3.32 -2.43,0.64 -0.62,1.26 -2.56,2.25 l -1.17,1.14 c 0.1,2.46 -2.21,-0.16 -1.1,2.51 -0.46,-2 -3.44,1.53 -3.52,-2.56 l 0.07,-3.23 c -1,0.32 -1.46,3.51 -2.16,5 l -0.49,-1.43 c 0.27,4.92 -2.57,-0.21 -3.46,3.67 -2.38,-1.58 -5.62,0.36 -7,-2.5 -1.54,1.7 -2.86,3.65 -4.92,2.86 0.33,-0.51 0.84,-0.72 0.82,-1.78 -1.39,-1.28 -1.54,0 -2.55,1 0.16,-0.76 -2.8,-2.54 -4.4,-4.08 -1.5,1.68 -0.55,4.23 -0.5,5.86 -2.23,-4.61 -4.3,3.72 -6.87,-0.39 0.48,-0.74 2.12,-2.68 0.52,-3.71 -2.29,-4.59 -2.59,3.92 -5.42,2.11 l 1.25,3.86 c -1.51,-2.26 -3.25,3 -3.67,-1.12 -0.58,1.57 -3.14,-0.8 -2.2,3 -4.64,-2.54 -9.45,3.74 -13.29,-2.73 -0.45,0.75 -2.05,0.35 -1.35,2.27 1.4,2 1.05,-1.77 1.7,-0.38 -0.5,0.21 -0.4,1.29 -0.35,1.83 -1.43,-0.65 -2.49,-0.75 -1.94,-4.17 -3.31,-1.83 -1.55,7.18 -5.4,6.44 -0.17,-1.62 -0.57,-2.16 -1.56,-1.67 l -1.37,3.16 c -2.42,-0.11 -2.1,-3.32 -2.75,-6 -1.13,0.74 -2.67,0.95 -2.77,3.08 l -2.28,-3 c 1.66,2.18 -0.64,1.85 -1.06,2.63 l 0.42,-0.78 c -0.49,-1.1 -1.76,-0.07 -2.4,0.42 0.57,1.63 2.18,2 3.08,2.28 -0.35,1.32 -1.39,1.26 -1.89,2.83 -0.34,-2.68 -2.44,-1.42 -3.48,-1.47 -1.26,-0.31 -0.68,2.63 -1,2.62 -0.36,-1.36 -1.86,0.25 -1.47,-1.88 0.27,-0.54 1.19,1.07 1.52,-0.27 -1,-0.84 -1.48,-3.21 -2.58,-1.08 -0.81,1.6 1.59,5.09 -1,4 l 0.45,-2.94 -2.38,-0.81 0.52,2.4 -0.5,-1.07 c 0,2.67 -2.9,1.61 -2.62,4.55 -0.95,0.52 -2.58,-1.07 -3.64,-1.08 l 0.14,-0.26 c -1.57,-1.08 -2.92,0.26 -3.48,2.13 l -0.09,-0.53 a 3.15,3.15 0 0 0 -2.56,2.38 c -2.14,-1.34 -3.08,-8.79 -4.06,-5.32 -1.67,0.52 -1.37,5.07 -0.27,6.38 -3.44,-0.68 -5.65,4.21 -9.51,1.4 -0.13,1.08 0.32,1.59 -0.39,2.42 -4.64,0.45 -8.29,5.54 -13.22,2.13 0.92,-1.41 -0.7,-2.37 -1.16,-3.69 -0.34,2.45 -2,-1.73 -1.15,2 0.81,2.07 1.05,3.13 2.54,3.56 -2.19,2 -6.07,3.38 -8.18,1.91 1.05,0.72 0.72,1.56 0.37,2.38 -1,-3.41 -3,-3.26 -4.07,-1.57 l 0.52,2.1 -1.68,-1.77 c -0.32,0.84 0.91,4.48 -1.2,3 l -1.2,-2 c -0.89,2.18 -1.95,5.7 -4.16,4.61 l -2.39,-2.46 c -0.56,0.58 -1,2.8 0.47,3.19 -3.37,-0.74 -5.21,-0.29 -7,-2.51 -2.33,8 -9,10.76 -14.48,12.64 l -0.45,-1.57 c -2,-0.79 0.33,2.93 -1.1,2.31 -0.13,-1.62 -2.39,-2.65 -2,-4.86 -2.73,-0.71 -1.6,3.7 -2.65,4.93 0.62,2.05 0.55,-1.7 1.33,0.9 0.07,0.79 -3.5,-0.35 -2.56,2.75 -1,-0.95 -1.53,-3.29 -1.76,-4.61 l -0.65,2 c -3,-2.8 0.91,-7.65 -2.53,-11.23 l -1,0.94 c -2.45,-2.61 1.65,-4.78 -1.78,-4.61 -0.68,2 0.07,6.74 1.77,7.58 -2.31,1.93 1.78,7.53 -1.15,8.51 -1.52,-1.41 2.08,-1.41 0.49,-3.59 -2.38,-1.82 -2.09,2.51 -3.64,2.2 1.8,0.52 2,4 1.39,4.91 -2,-0.75 -0.29,-3.2 -2.45,-2.6 0.41,1.85 -0.87,4 1.25,4.42 1,4.17 -2.57,-0.13 -2.33,3.34 -1.87,-2.41 -0.71,-7.18 -3.54,-7.53 1.51,2.44 -1.15,4.76 1.75,8.08 -1.19,-0.35 -2.21,-2.35 -2.3,-4.23 -2,-1 -0.85,6.09 -3.61,1.13 l 0.79,2.83 c -0.79,-0.69 -1.64,-1.09 -2.93,-2.23 -1.13,0.42 -1.84,5.21 -3.61,1.17 -0.15,0.58 -2.71,1.59 -0.46,3.88 2.32,0.94 0.82,-2.85 3.41,0.47 -2.5,-2.53 -2,1.45 -2.42,2.89 l -0.87,Line truncated
|
||||
id="path1085" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 85.09,415.18 c 1.46,1.19 3.4,1.08 3.66,3.81 -1.09,-1.3 -2.88,-2.37 -3.66,-3.81 z"
|
||||
id="path1087" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 132.43,407.43 c -0.22,-0.5 0.91,0.32 1.18,0.5 -0.39,0.39 -0.06,2 -0.9,1.37 0.4,-0.39 -0.11,-1.09 -0.28,-1.87 z"
|
||||
id="path1089" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 142.64,402.83 c 0.64,1.48 -0.8,3.76 -1.92,4.62 z"
|
||||
id="path1091" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 154.9,403.61 c 1.43,0.77 1.57,1.54 0.5,2.07 z"
|
||||
id="path1093" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 153.79,400 c 0.73,-0.44 1.56,0.19 2.37,0.81 -0.69,-1.17 -1.34,1.74 -2.37,-0.81 z"
|
||||
id="path1095" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 175.79,393.79 c 0.42,-0.36 0.86,-2.08 2.11,-0.7 -1.07,-0.87 -1.41,3 -2.11,0.7 z"
|
||||
id="path1097" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 184,387 c 0.35,-0.05 0.6,0.16 0.76,-0.41 a 1.43,1.43 0 0 1 0.4,2.09 z"
|
||||
id="path1099" />
|
||||
<polygon
|
||||
class="cls-1"
|
||||
points="360.42,323.05 360.33,321.44 361.4,322.06 "
|
||||
id="polygon1101" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 443.86,316.79 c 1.15,-1 0.72,1.54 0.9,1.78 -1.01,0.14 0.44,-1.97 -0.9,-1.78 z"
|
||||
id="path1103" />
|
||||
<polygon
|
||||
class="cls-1"
|
||||
points="488.93,312.81 489.54,309.55 489.28,312.82 "
|
||||
id="polygon1105" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.intellijcommentatorplugin.CaseChangerAction.Transform;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static com.kingsrook.intellijcommentatorplugin.CaseChangerAction.getReplacementText;
|
||||
import static com.kingsrook.intellijcommentatorplugin.CaseChangerAction.toSubWords;
|
||||
import static com.kingsrook.intellijcommentatorplugin.CaseChangerAction.toWords;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for CreateBoxCommentAction.
|
||||
*******************************************************************************/
|
||||
class CaseChangerActionTest
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testToWords()
|
||||
{
|
||||
assertEquals(List.of("foo_bar"), toWords("foo_bar"));
|
||||
assertEquals(List.of("foo", " ", "bar"), toWords("foo bar"));
|
||||
assertEquals(List.of("foo", "\n", "bar"), toWords("foo\nbar"));
|
||||
assertEquals(List.of(" ", "foo", "\n ", "bar", " "), toWords(" foo\n bar "));
|
||||
// dash handling is intentionally disabled (see isWordPart and the commented-out *_DASHES transforms),
|
||||
// so a dash is a separator, not part of a word.
|
||||
assertEquals(List.of("one", "-", "two"), toWords("one-two"));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testToSubWords()
|
||||
{
|
||||
assertEquals(List.of("foo", "bar"), toSubWords("foo_bar"));
|
||||
assertEquals(List.of("foo", "Bar"), toSubWords("fooBar"));
|
||||
assertEquals(List.of("Foo", "Bar"), toSubWords("FooBar"));
|
||||
// dash handling is intentionally disabled (see isWordPart and the commented-out *_DASHES transforms),
|
||||
// so a dash is not a sub-word separator.
|
||||
assertEquals(List.of("foo-bar"), toSubWords("foo-bar"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testReplacementText()
|
||||
{
|
||||
assertEquals("foo_bar", getReplacementText("fooBar", Transform.LOWER_CASE_UNDERSCORES));
|
||||
assertEquals("FooBar", getReplacementText("fooBar", Transform.PASCAL_CASE));
|
||||
assertEquals("fooBar", getReplacementText("foo_bar", Transform.CAMEL_CASE));
|
||||
assertEquals("FooBar FizBin", getReplacementText("fooBar fizBin", Transform.PASCAL_CASE));
|
||||
assertEquals("foo-bar", getReplacementText("foo-bar", Transform.CAMEL_CASE));
|
||||
}
|
||||
|
||||
}
|
||||
+26
-1
@@ -114,6 +114,31 @@ class CreateBoxCommentActionTest
|
||||
////////////////////////////////////////////////////
|
||||
assertEquals(expected, getReplacementText("Test\n" +
|
||||
" In Here"));
|
||||
|
||||
//////////////////////////////////////
|
||||
// avoid index out of bounds error! //
|
||||
//////////////////////////////////////
|
||||
expected = " /////////////\n" +
|
||||
" // Test //\n" +
|
||||
" // //\n" +
|
||||
" // In Here //\n" +
|
||||
" /////////////";
|
||||
|
||||
assertEquals(expected, getReplacementText(" Test\n" +
|
||||
"\n" +
|
||||
" In Here"));
|
||||
|
||||
assertEquals(expected, getReplacementText(" Test\n" +
|
||||
" \n" +
|
||||
" In Here"));
|
||||
|
||||
assertEquals(expected, getReplacementText(" Test\n" +
|
||||
" \n" +
|
||||
" In Here"));
|
||||
|
||||
assertEquals(expected, getReplacementText(" Test\n" +
|
||||
" \n" +
|
||||
" In Here"));
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +149,7 @@ class CreateBoxCommentActionTest
|
||||
private String getReplacementText(String input)
|
||||
{
|
||||
CreateBoxCommentAction action = new CreateBoxCommentAction();
|
||||
String output = action.getReplacementText(input).toString();
|
||||
String output = action.getReplacementText(input, "/").toString();
|
||||
|
||||
System.out.printf("Input:\n%s\nOutput:\n%s\n", input, output);
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for com.kingsrook.intellijcommentatorplugin.GetSetWithAction
|
||||
*******************************************************************************/
|
||||
class GetSetWithActionTest
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testParseTypeAndNameFromDeclarationLine()
|
||||
{
|
||||
assertEquals(Pair.of("String", "foo"), GetSetWithAction.parseTypeAndNameFromDeclarationLine(" private String foo;"));
|
||||
assertEquals(Pair.of("String", "foo"), GetSetWithAction.parseTypeAndNameFromDeclarationLine(" private String foo = \"hello\";"));
|
||||
assertEquals(Pair.of("String[]", "foo"), GetSetWithAction.parseTypeAndNameFromDeclarationLine(" private String[] foo = {};"));
|
||||
assertEquals(Pair.of("List<String>", "foo"), GetSetWithAction.parseTypeAndNameFromDeclarationLine(" private List<String> foo = new ArrayList<>();"));
|
||||
assertEquals(Pair.of("Map<String, Integer>", "foo"), GetSetWithAction.parseTypeAndNameFromDeclarationLine(" private Map<String, Integer> foo = new HashMap<>();"));
|
||||
assertEquals(Pair.of("Map<String, List<Integer>>", "foo"), GetSetWithAction.parseTypeAndNameFromDeclarationLine(" private Map<String, List<Integer>> foo = new HashMap<>();"));
|
||||
assertNull(GetSetWithAction.parseTypeAndNameFromDeclarationLine(" // comment line"));
|
||||
assertNull(GetSetWithAction.parseTypeAndNameFromDeclarationLine(" public Constructor()"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2023. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for URIDecodeAction
|
||||
*******************************************************************************/
|
||||
class URIDecodeActionTest
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void test()
|
||||
{
|
||||
URIDecodeAction uriDecodeAction = new URIDecodeAction();
|
||||
StringBuilder replacementText = uriDecodeAction.getReplacementText("%7B%22criteria%22:%5B%7B%22fieldName%22");
|
||||
assertEquals("{\"criteria\":[{\"fieldName\"", replacementText.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Kingsrook IntelliJ Commentator Plugin
|
||||
* Copyright (C) 2022. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/intellij-commentator-plugin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.intellijcommentatorplugin;
|
||||
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for CreateBoxCommentAction.
|
||||
*******************************************************************************/
|
||||
class WrapCommentActionTest
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
assertEquals("""
|
||||
////////////////
|
||||
// one two //
|
||||
// three four //
|
||||
// five six //
|
||||
// seven //
|
||||
// eight nine //
|
||||
// ten //
|
||||
////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
/////////////////////////////////
|
||||
// one two three four five six //
|
||||
// seven eight nine ten //
|
||||
/////////////////////////////////""", 10));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testWordLongerThanMaxLineLength()
|
||||
{
|
||||
assertEquals("""
|
||||
/////////////////
|
||||
// one two //
|
||||
// three //
|
||||
// fourfivesix //
|
||||
// seven //
|
||||
// eight nine //
|
||||
// ten //
|
||||
/////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
///////////////////////////////
|
||||
// one two three fourfivesix //
|
||||
// seven eight nine ten //
|
||||
///////////////////////////////""", 10));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testDoubleSpaceAfterPeriodIsPreserved()
|
||||
{
|
||||
assertEquals("""
|
||||
////////////////
|
||||
// one two //
|
||||
// three four //
|
||||
// five. six //
|
||||
// seven //
|
||||
// eight nine //
|
||||
// ten //
|
||||
////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
///////////////////////////////////
|
||||
// one two three four five. six seven eight nine ten //
|
||||
///////////////////////////////""", 10));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testDoubleSpaceAfterPeriodIsLostAtEndOfWrappedLines()
|
||||
{
|
||||
assertEquals("""
|
||||
////////////////
|
||||
// one two //
|
||||
// three four //
|
||||
// five siix. //
|
||||
// seven //
|
||||
// eight nine //
|
||||
// ten //
|
||||
////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
///////////////////////////////////
|
||||
// one two three four five siix. seven eight nine ten //
|
||||
///////////////////////////////""", 10));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testLeadingSpacesAtStartOfLineArePreserved()
|
||||
{
|
||||
assertEquals("""
|
||||
////////////////
|
||||
// one two //
|
||||
// three four //
|
||||
// - five //
|
||||
// - six //
|
||||
////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
///////////////////////////////////
|
||||
// one two three four
|
||||
// - five
|
||||
// - six
|
||||
///////////////////////////////""", 10));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testMultipleSpacesAfterWordNotLostToShorterNextWord()
|
||||
{
|
||||
assertEquals("""
|
||||
///////////////
|
||||
// one. //
|
||||
// two three //
|
||||
// four //
|
||||
///////////////""",
|
||||
doReplacementNoWrap("""
|
||||
///////////////////////////////////
|
||||
// one. two //
|
||||
// three four //
|
||||
///////////////////////////////""", 10));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testWithNestedBulletListsAndDoubleSpaceAfterPeriod()
|
||||
{
|
||||
assertEquals("""
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// do a thing this is a comment that is much longer so long in fact i think //
|
||||
// that needs wrapped onto more lines //
|
||||
// - but what about this? //
|
||||
// - and that? //
|
||||
// - and other things? this is all really important so i should probably //
|
||||
// say more words keep typing. Seriously. I mean it. And I like //
|
||||
// double-spaces after periods. for real... //
|
||||
//////////////////////////////////////////////////////////////////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// do a thing this is a comment that is much longer so long in fact i think that needs wrapped onto more lines //
|
||||
// - but what about this?
|
||||
// - and that?
|
||||
// - and other things? this is all really important so i should probably
|
||||
// say more words keep typing. Seriously. I mean it. And I like double-spaces after periods. for real...
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
""", 74));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testSentenceEndingPunctuationAtEOL()
|
||||
{
|
||||
assertEquals("""
|
||||
///////////////////////////////////////////////
|
||||
// This is a sentence that ends in a period. //
|
||||
// this should stay on a second line. //
|
||||
///////////////////////////////////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// This is a sentence that ends in a period. //
|
||||
// this should stay on a second line. //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
""", 74));
|
||||
|
||||
assertEquals("""
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This is a sentence that ends in a period. //
|
||||
// here are long words that should wrap and here are long words that should //
|
||||
// wrap and here are long words that should wrap and here are long words that //
|
||||
// should wrap. //
|
||||
////////////////////////////////////////////////////////////////////////////////""",
|
||||
doReplacementNoWrap("""
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// This is a sentence that ends in a period. //
|
||||
// here are long words that should wrap and here are long words that should wrap and here are long words that should wrap and here are long words that should wrap. //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
""", 74));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
public void testRewrap()
|
||||
{
|
||||
assertEquals("""
|
||||
///////////////////////////////////////////////////////////////
|
||||
// this is a comment. it has some sentences in it. some of //
|
||||
// those are long, and some are short, or long, who knows? //
|
||||
///////////////////////////////////////////////////////////////""",
|
||||
doReplacementWithWrap("""
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// this is a comment. it has some sentences in it. some of those are long, and some are short, //
|
||||
// or long, who knows? //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
""", 74));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Run the getReplacementText method on the given input, with the DO_NOT_REWRAP option
|
||||
*******************************************************************************/
|
||||
private String doReplacementNoWrap(String input, int maxLength)
|
||||
{
|
||||
return doReplacement(maxLength, input, WrapCommentAction.Transform.DO_NOT_REWRAP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Run the getReplacementText method on the given input, with the DO_REWRAP option
|
||||
*******************************************************************************/
|
||||
private String doReplacementWithWrap(String input, int maxLength)
|
||||
{
|
||||
return doReplacement(maxLength, input, WrapCommentAction.Transform.DO_REWRAP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static String doReplacement(int maxLength, String input, WrapCommentAction.Transform doNotRewrap)
|
||||
{
|
||||
WrapCommentAction action = new WrapCommentAction();
|
||||
String output = action.getReplacementText(input, "/", doNotRewrap, maxLength).toString();
|
||||
|
||||
System.out.printf("Input:\n%s\nOutput:\n%s\n", input, output);
|
||||
|
||||
return (output);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user