aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Case Conversion.iml13
-rw-r--r--LICENSE13
-rw-r--r--README.md17
-rw-r--r--resources/META-INF/plugin.xml76
-rw-r--r--src/me/laria/code/idea_caseconv/CamelCaseAction.java18
-rw-r--r--src/me/laria/code/idea_caseconv/DashCaseAction.java10
-rw-r--r--src/me/laria/code/idea_caseconv/FlipCaseAction.java12
-rw-r--r--src/me/laria/code/idea_caseconv/LowerCaseAction.java8
-rw-r--r--src/me/laria/code/idea_caseconv/PascalCaseAction.java10
-rw-r--r--src/me/laria/code/idea_caseconv/Replacement.java25
-rw-r--r--src/me/laria/code/idea_caseconv/ScreamingSnakeCaseAction.java10
-rw-r--r--src/me/laria/code/idea_caseconv/SelectionReplacerAction.java59
-rw-r--r--src/me/laria/code/idea_caseconv/SeparateWordsAction.java10
-rw-r--r--src/me/laria/code/idea_caseconv/SnakeCaseAction.java10
-rw-r--r--src/me/laria/code/idea_caseconv/UpperCaseAction.java8
-rw-r--r--src/me/laria/code/idea_caseconv/WordSplitConverter.java36
-rw-r--r--src/me/laria/code/idea_caseconv/WordTransformer.java7
18 files changed, 344 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ba1f399
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+Case Conversion.jar
+out/
diff --git a/Case Conversion.iml b/Case Conversion.iml
new file mode 100644
index 0000000..e025b20
--- /dev/null
+++ b/Case Conversion.iml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PLUGIN_MODULE" version="4">
+ <component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..90107a0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2004 Sam Hocevar
+ 14 rue de Plaisance, 75014 Paris, France
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d7cc58b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+Case Conversion
+===============
+
+A plugin for JetBrain IDEs to convert between cases.
+
+The plugin provides actions to convert to these cases:
+
+- `snake_case`
+- `dash-case`
+- `camelCase`
+- `PascalCase`
+- `SCREAMING_SNAKE_CASE`
+- `UPPER CASE`
+- `lower case`
+- `fLIP cASE`
+
+The Plugin was inspired by the [Case Conversion Plugin for SublimeText](https://packagecontrol.io/packages/Case%20Conversion). \ No newline at end of file
diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
new file mode 100644
index 0000000..c532213
--- /dev/null
+++ b/resources/META-INF/plugin.xml
@@ -0,0 +1,76 @@
+<idea-plugin>
+ <id>me.laria.code.idea_caseconv</id>
+ <name>Case conversion</name>
+ <version>0.5</version>
+ <vendor email="laria@laria.me" url="https://code.laria.me">Laria Chabowski</vendor>
+
+ <description><![CDATA[<html>
+ <p>Convert between cases.</p>
+ <p>The Plugin provides actions to convert to the following cases:</p>
+ <ul>
+ <li>snake_case</li>
+ <li>dash-case</li>
+ <li>camelCase</li>
+ <li>PascalCase</li>
+ <li>SCREAMING_SNAKE_CASE</li>
+ <li>UPPER CASE</li>
+ <li>lower case</li>
+ <li>fLIP cASE</li>
+ </ul>
+ </html>]]></description>
+
+ <change-notes><![CDATA[]]>
+ </change-notes>
+
+ <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
+ <idea-version since-build="173.0"/>
+
+ <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
+ on how to target different products -->
+ <depends>com.intellij.modules.lang</depends>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <!-- Add your extensions here -->
+ </extensions>
+
+ <actions>
+ <!-- Add your actions here -->
+ <action id="me.laria.code.idea_caseconv.SnakeCaseAction" class="me.laria.code.idea_caseconv.SnakeCaseAction"
+ text="Convert Case: snake__case">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.DashCaseAction" class="me.laria.code.idea_caseconv.DashCaseAction"
+ text="Convert Case: dash-case">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.SeparateWordsAction" class="me.laria.code.idea_caseconv.SeparateWordsAction"
+ text="Convert case: separate words">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.CamelCaseAction" class="me.laria.code.idea_caseconv.CamelCaseAction"
+ text="Convert Case: camelCase">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.PascalCaseAction" class="me.laria.code.idea_caseconv.PascalCaseAction"
+ text="Convert Case: PascalCase">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.ScreamingSnakeCaseAction"
+ class="me.laria.code.idea_caseconv.ScreamingSnakeCaseAction" text="Convert Case: SCREAMING__SNAKE__CASE">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.UpperCaseAction" class="me.laria.code.idea_caseconv.UpperCaseAction"
+ text="Convert Case: UPPER CASE">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.LowerCaseAction" class="me.laria.code.idea_caseconv.LowerCaseAction"
+ text="Convert Case: lower case">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ <action id="me.laria.code.idea_caseconv.FlipCaseAction" class="me.laria.code.idea_caseconv.FlipCaseAction"
+ text="Convert Case: fLIP cASE">
+ <add-to-group group-id="EditMenu" anchor="first"/>
+ </action>
+ </actions>
+
+</idea-plugin> \ No newline at end of file
diff --git a/src/me/laria/code/idea_caseconv/CamelCaseAction.java b/src/me/laria/code/idea_caseconv/CamelCaseAction.java
new file mode 100644
index 0000000..93ca85b
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/CamelCaseAction.java
@@ -0,0 +1,18 @@
+package me.laria.code.idea_caseconv;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Optional;
+
+public class CamelCaseAction extends SelectionReplacerAction {
+ @NotNull
+ public static String ucfirst(String s) {
+ s = s.toLowerCase();
+ return s.substring(0, 1).toUpperCase().concat(s.substring(1));
+ }
+
+ @Override
+ protected String replace(String s) {
+ return WordSplitConverter.convert(s, "", (i, part) -> Optional.of(i == 0 ? part.toLowerCase() : ucfirst(part)));
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/DashCaseAction.java b/src/me/laria/code/idea_caseconv/DashCaseAction.java
new file mode 100644
index 0000000..5e030ab
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/DashCaseAction.java
@@ -0,0 +1,10 @@
+package me.laria.code.idea_caseconv;
+
+import java.util.Optional;
+
+public class DashCaseAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ return WordSplitConverter.convert(s, "-", (i, s1) -> Optional.of(s1.toLowerCase()));
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/FlipCaseAction.java b/src/me/laria/code/idea_caseconv/FlipCaseAction.java
new file mode 100644
index 0000000..22df45a
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/FlipCaseAction.java
@@ -0,0 +1,12 @@
+package me.laria.code.idea_caseconv;
+
+public class FlipCaseAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ StringBuilder builder = new StringBuilder();
+
+ s.codePoints().forEach(c -> builder.appendCodePoint(Character.isLowerCase(c) ? Character.toUpperCase(c) : Character.toLowerCase(c)));
+
+ return builder.toString();
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/LowerCaseAction.java b/src/me/laria/code/idea_caseconv/LowerCaseAction.java
new file mode 100644
index 0000000..d32507e
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/LowerCaseAction.java
@@ -0,0 +1,8 @@
+package me.laria.code.idea_caseconv;
+
+public class LowerCaseAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ return s.toLowerCase();
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/PascalCaseAction.java b/src/me/laria/code/idea_caseconv/PascalCaseAction.java
new file mode 100644
index 0000000..fb13265
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/PascalCaseAction.java
@@ -0,0 +1,10 @@
+package me.laria.code.idea_caseconv;
+
+import java.util.Optional;
+
+public class PascalCaseAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ return WordSplitConverter.convert(s, "", (i, part) -> Optional.of(CamelCaseAction.ucfirst(part)));
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/Replacement.java b/src/me/laria/code/idea_caseconv/Replacement.java
new file mode 100644
index 0000000..804812b
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/Replacement.java
@@ -0,0 +1,25 @@
+package me.laria.code.idea_caseconv;
+
+import com.intellij.openapi.editor.Document;
+import org.jetbrains.annotations.NotNull;
+
+class Replacement implements Comparable<Replacement> {
+ private final int a;
+ private final int b;
+ private final String s;
+
+ public Replacement(int a, int b, String s) {
+ this.a = Integer.min(a, b);
+ this.b = Integer.max(a, b);
+ this.s = s;
+ }
+
+ public void doReplace(Document doc) {
+ doc.replaceString(this.a, this.b, this.s);
+ }
+
+ @Override
+ public int compareTo(@NotNull Replacement o) {
+ return Integer.compare(this.a, o.a);
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/ScreamingSnakeCaseAction.java b/src/me/laria/code/idea_caseconv/ScreamingSnakeCaseAction.java
new file mode 100644
index 0000000..c77bbfe
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/ScreamingSnakeCaseAction.java
@@ -0,0 +1,10 @@
+package me.laria.code.idea_caseconv;
+
+import java.util.Optional;
+
+public class ScreamingSnakeCaseAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ return WordSplitConverter.convert(s, "_", (i, part) -> Optional.of(part.toUpperCase()));
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/SelectionReplacerAction.java b/src/me/laria/code/idea_caseconv/SelectionReplacerAction.java
new file mode 100644
index 0000000..692fd6c
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/SelectionReplacerAction.java
@@ -0,0 +1,59 @@
+package me.laria.code.idea_caseconv;
+
+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.Caret;
+import com.intellij.openapi.editor.CaretModel;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+
+import java.util.ArrayList;
+
+abstract class SelectionReplacerAction extends AnAction {
+ @Override
+ public void update(final AnActionEvent e) {
+ //Get required data keys
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+ final Editor editor = e.getData(CommonDataKeys.EDITOR);
+ //Set visibility only in case of existing project and editor and if some text in the editor is selected
+ e.getPresentation().setVisible(
+ project != null
+ && editor != null
+ && editor.getSelectionModel().hasSelection()
+ );
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent anActionEvent) {
+ Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
+ Project project = anActionEvent.getData(CommonDataKeys.PROJECT);
+ assert editor != null;
+ assert project != null;
+
+ CaretModel caretModel = editor.getCaretModel();
+ Document document = editor.getDocument();
+
+ ArrayList<Replacement> replacements = new ArrayList<>();
+ for (Caret caret : caretModel.getAllCarets()) {
+ if (!caret.hasSelection()) {
+ continue;
+ }
+
+ replacements.add(new Replacement(
+ caret.getSelectionStart(),
+ caret.getSelectionEnd(),
+ this.replace(caret.getSelectedText())
+ ));
+ }
+
+ // Sort in reverse order so a replacement won't mess up the indices of the other replacements
+ replacements.sort((o1, o2) -> -o1.compareTo(o2));
+
+ WriteCommandAction.runWriteCommandAction(project, () -> replacements.forEach(r -> r.doReplace(document)));
+ }
+
+ abstract protected String replace(String s);
+}
diff --git a/src/me/laria/code/idea_caseconv/SeparateWordsAction.java b/src/me/laria/code/idea_caseconv/SeparateWordsAction.java
new file mode 100644
index 0000000..6f3f4fe
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/SeparateWordsAction.java
@@ -0,0 +1,10 @@
+package me.laria.code.idea_caseconv;
+
+import java.util.Optional;
+
+public class SeparateWordsAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ return WordSplitConverter.convert(s, " ", (i, part) -> Optional.of(part.toLowerCase()));
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/SnakeCaseAction.java b/src/me/laria/code/idea_caseconv/SnakeCaseAction.java
new file mode 100644
index 0000000..9853676
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/SnakeCaseAction.java
@@ -0,0 +1,10 @@
+package me.laria.code.idea_caseconv;
+
+import java.util.Optional;
+
+public class SnakeCaseAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ return WordSplitConverter.convert(s, "_", (i, part) -> Optional.of(part.toLowerCase()));
+ }
+} \ No newline at end of file
diff --git a/src/me/laria/code/idea_caseconv/UpperCaseAction.java b/src/me/laria/code/idea_caseconv/UpperCaseAction.java
new file mode 100644
index 0000000..8478f4f
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/UpperCaseAction.java
@@ -0,0 +1,8 @@
+package me.laria.code.idea_caseconv;
+
+public class UpperCaseAction extends SelectionReplacerAction {
+ @Override
+ protected String replace(String s) {
+ return s.toUpperCase();
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/WordSplitConverter.java b/src/me/laria/code/idea_caseconv/WordSplitConverter.java
new file mode 100644
index 0000000..9b87a25
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/WordSplitConverter.java
@@ -0,0 +1,36 @@
+package me.laria.code.idea_caseconv;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+class WordSplitConverter {
+ private static List<String> split(String s) {
+ Pattern decamelize = Pattern.compile("(?<![A-Z])[A-Z]");
+ s = decamelize.matcher(s).replaceAll(" $0");
+
+ String[] all_parts = s.split("[\\s_-]");
+ ArrayList<String> parts = new ArrayList<>();
+ for (String p : all_parts) {
+ p = p.trim();
+ if (!p.equals("")) {
+ parts.add(p.toLowerCase());
+ }
+ }
+
+ return parts;
+ }
+
+ public static String convert(String in, String glue, WordTransformer transform) {
+ List<String> partsIn = split(in);
+ ArrayList<String> partsOut = new ArrayList<>();
+
+ int i = 0;
+ for (String part : partsIn) {
+ transform.transform(i, part).ifPresent(partsOut::add);
+ i++;
+ }
+
+ return String.join(glue, partsOut);
+ }
+}
diff --git a/src/me/laria/code/idea_caseconv/WordTransformer.java b/src/me/laria/code/idea_caseconv/WordTransformer.java
new file mode 100644
index 0000000..ad0aeab
--- /dev/null
+++ b/src/me/laria/code/idea_caseconv/WordTransformer.java
@@ -0,0 +1,7 @@
+package me.laria.code.idea_caseconv;
+
+import java.util.Optional;
+
+interface WordTransformer {
+ Optional<String> transform(int i, String s);
+}