From 252d68f14bcf137e2532caa65e3c29a64cf78a70 Mon Sep 17 00:00:00 2001 From: jdha97 <61319894+jdha97@users.noreply.github.com> Date: Sun, 23 Jun 2024 10:23:58 -0400 Subject: [PATCH] even more stuff v3 --- build.gradle.kts | 2 - ...NormalBox.kt => CodeDividerBoxStandard.kt} | 241 ++++++++++++++---- .../codedivider/action/CodeDividerLine.kt | 182 +++++++++---- .../CodeDividerSettingsConfigurable.kt | 163 ++++++------ .../settings/CodeDividerSettingsState.kt | 139 ++-------- src/main/resources/META-INF/plugin.xml | 240 +++++++++++++---- 6 files changed, 622 insertions(+), 345 deletions(-) rename src/main/kotlin/com/github/jdha/codedivider/action/{CodeDividerNormalBox.kt => CodeDividerBoxStandard.kt} (57%) diff --git a/build.gradle.kts b/build.gradle.kts index 1b56e5e..5201b4e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,6 @@ plugins { alias(libs.plugins.changelog) // Gradle Changelog Plugin alias(libs.plugins.qodana) // Gradle Qodana Plugin alias(libs.plugins.kover) // Gradle Kover Plugin - kotlin("plugin.serialization") version "2.0.0" } group = properties("pluginGroup").get() @@ -26,7 +25,6 @@ repositories { mavenCentral() } // https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog dependencies { // implementation(libs.exampleLibrary) - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0") } // Set the JVM language level used to build the project. diff --git a/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerNormalBox.kt b/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerBoxStandard.kt similarity index 57% rename from src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerNormalBox.kt rename to src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerBoxStandard.kt index a20c291..4574f4a 100644 --- a/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerNormalBox.kt +++ b/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerBoxStandard.kt @@ -1,8 +1,8 @@ package com.github.jdha.codedivider.action -import com.github.jdha.codedivider.settings.BoxSettings import com.github.jdha.codedivider.settings.BoxType import com.github.jdha.codedivider.settings.CodeDividerSettingsState +import com.github.jdha.codedivider.settings.CommentSymbolType import com.intellij.lang.LanguageCommenters import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent @@ -14,35 +14,60 @@ import kotlin.math.min // ━━ SAMPLE BOXES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -// ┌──────────────────────────────────────┐ -// │ Lorem ipsumdolor sit amet, │ -// │ consectetur adipiscing elit, sed │ -// │ do eiusmod tempor incididunt │ -// └──────────────────────────────────────┘ +// ┌──────────────────────────────────────────────────────────┐ +// │ normal, single line │ +// └──────────────────────────────────────────────────────────┘ -// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -// ┃ Lorem ipsumdolor sit amet, ┃ -// ┃ consectetur adipiscing elit, sed ┃ -// ┃ do eiusmod tempor incididunt ┃ -// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +// ┌──────────────────────────────────────────────────────────┐ +// │ normal, multi line │ +// │ Lorem ipsum dolor sit amet, consectetur adipiscing │ +// │ elit, sed do eiusmod tempor incididunt ut labore et │ +// │ dolore magna aliqua. │ +// └──────────────────────────────────────────────────────────┘ -// ╭─────────────────────────────────────────────────────────╮ -// │ COMMANDS │ -// │ COMMANDS │ -// │ COMMANDS │ -// ╰─────────────────────────────────────────────────────────╯ +// ╭──────────────────────────────────────────────────────────╮ +// │ box, rounded │ +// ╰──────────────────────────────────────────────────────────╯ -// ╔══════════════════════════════════════╗ -// ║ BOXES & LINES ║ -// ╚══════════════════════════════════════╝ +// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +// ┃ box, heavy ┃ +// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ -// ┌ ┐ -// │ BOXES │ -// └ ┘ +// ╔══════════════════════════════════════════════════════════╗ +// ║ box, double line ║ +// ╚══════════════════════════════════════════════════════════╝ -// ╭─ ─╮ -// │ COMMANDS │ -// ╰─ ─╯ +// ┌─ ─┐ +// │ box, open top │ +// └─ ─┘ + +// ╭─ ─╮ +// │ box, open top, rounded │ +// ╰─ ─╯ + +// ┏━ ━┓ +// ┃ box, open top, heavy ┃ +// ┗━ ━┛ + +// ╔═ ═╗ +// ║ box, open top, double line ║ +// ╚═ ═╝ + +// ┌──────────────────────────────────────────────────────────┐ +// box, open side +// └──────────────────────────────────────────────────────────┘ + +// ╭──────────────────────────────────────────────────────────╮ +// box, open side, rounded +// ╰──────────────────────────────────────────────────────────╯ + +// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +// box, open side, heavy +// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + +// ╔══════════════════════════════════════════════════════════╗ +// box, open side, double line +// ╚══════════════════════════════════════════════════════════╝ // ━━ LINE CONSTANTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -80,18 +105,89 @@ const val DOUBLE_CORNER_BR = "╝" // ━━ ACTIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -class CodeDividerNormalBox : AnAction() { +// solid side +class CodeDividerBoxStandard : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.NORMAL) + } +} + +class CodeDividerBoxRounded : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.ROUNDED) + } +} + +class CodeDividerBoxHeavy : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.HEAVY) + } +} + +class CodeDividerBoxDouble : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.DOUBLE) + } +} + +// open top +class CodeDividerBoxNormalOpenTop : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.NORMAL_OPEN_TOP) + } +} + +class CodeDividerBoxRoundedOpenTop : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.ROUNDED_OPEN_TOP) + } +} + +class CodeDividerBoxHeavyOpenTop : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.HEAVY_OPEN_TOP) + } +} + +class CodeDividerBoxDoubleOpenTop : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.DOUBLE_OPEN_TOP) + } +} + +// open side +class CodeDividerBoxNormalOpenSide : AnAction() { override fun actionPerformed(e: AnActionEvent) { - normalBox(e, BoxType.NORMAL, CodeDividerSettingsState.instance.boxSettings) + normalBox(e, BoxType.NORMAL_OPEN_SIDE) + } +} + +class CodeDividerBoxRoundedOpenSide : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.ROUNDED_OPEN_SIDE) + } +} + +class CodeDividerBoxHeavyOpenSide : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.HEAVY_OPEN_SIDE) + } +} + +class CodeDividerBoxDoubleOpenSide : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + normalBox(e, BoxType.DOUBLE_OPEN_SIDE) } } // ━━ LOGIC ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { +fun normalBox(e: AnActionEvent, boxType: BoxType) { // ── General Setup ──────────────────────────────────────────────────────────────────────────── val editor = e.getData(CommonDataKeys.EDITOR) ?: return + val settings = CodeDividerSettingsState.instance + val document = editor.document val caretModel = editor.caretModel val caretOffset = caretModel.offset @@ -111,9 +207,9 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { val (commentPrefix, commentSuffix) = getCommentSymbols( commenter = LanguageCommenters.INSTANCE.forLanguage(language), - errorOnNoCommentSymbol = boxSettings.errorOnNoCommentSymbol, + errorOnNoCommentSymbol = settings.errorOnNoCommentSymbol, commentPad = SPACE, - commentSymbolType = boxSettings.commentSymbolType, + commentSymbolType = CommentSymbolType.ONE_SINGLE_LINE, ) // ── Existing Text ──────────────────────────────────────────────────────────────────────────── @@ -132,7 +228,7 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { val cornerBR: String when (boxType) { - // ── Box, Heavy ─────────────────────────────────────────────────────────────────────────── + // solid side BoxType.NORMAL -> { vertical = NORMAL_VERTICAL horizontal = NORMAL_HORIZONTAL @@ -142,7 +238,6 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { cornerBR = NORMAL_CORNER_BR } - // ── Box, Rounded Corners ───────────────────────────────────────────────────────────────── BoxType.ROUNDED -> { vertical = ROUNDED_VERTICAL horizontal = ROUNDED_HORIZONTAL @@ -152,7 +247,6 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { cornerBR = ROUNDED_CORNER_BR } - // ── Box, Open ──────────────────────────────────────────────────────────────────────────── BoxType.HEAVY -> { vertical = HEAVY_VERTICAL horizontal = HEAVY_HORIZONTAL @@ -162,7 +256,6 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { cornerBR = HEAVY_CORNER_BR } - // ── Box, Double ────────────────────────────────────────────────────────────────────────── BoxType.DOUBLE -> { vertical = DOUBLE_VERTICAL horizontal = DOUBLE_HORIZONTAL @@ -172,39 +265,94 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { cornerBR = DOUBLE_CORNER_BR } - // ── Box, Open ──────────────────────────────────────────────────────────────────────────── + // open top BoxType.NORMAL_OPEN_TOP -> { vertical = NORMAL_VERTICAL - horizontal = " " + horizontal = SPACE cornerTL = NORMAL_CORNER_TL + NORMAL_HORIZONTAL cornerTR = NORMAL_HORIZONTAL + NORMAL_CORNER_TR cornerBL = NORMAL_CORNER_BL + NORMAL_HORIZONTAL cornerBR = NORMAL_HORIZONTAL + NORMAL_CORNER_BR } - // ── Box, Open, Rounded Corners ─────────────────────────────────────────────────────────── BoxType.ROUNDED_OPEN_TOP -> { vertical = ROUNDED_VERTICAL - horizontal = " " + horizontal = SPACE cornerTL = ROUNDED_CORNER_TL + ROUNDED_HORIZONTAL cornerTR = ROUNDED_HORIZONTAL + ROUNDED_CORNER_TR cornerBL = ROUNDED_CORNER_BL + ROUNDED_HORIZONTAL cornerBR = ROUNDED_HORIZONTAL + ROUNDED_CORNER_BR } + + BoxType.HEAVY_OPEN_TOP -> { + vertical = HEAVY_VERTICAL + horizontal = SPACE + cornerTL = HEAVY_CORNER_TL + HEAVY_HORIZONTAL + cornerTR = HEAVY_HORIZONTAL + HEAVY_CORNER_TR + cornerBL = HEAVY_CORNER_BL + HEAVY_HORIZONTAL + cornerBR = HEAVY_HORIZONTAL + HEAVY_CORNER_BR + } + + BoxType.DOUBLE_OPEN_TOP -> { + vertical = DOUBLE_VERTICAL + horizontal = SPACE + cornerTL = DOUBLE_CORNER_TL + DOUBLE_HORIZONTAL + cornerTR = DOUBLE_HORIZONTAL + DOUBLE_CORNER_TR + cornerBL = DOUBLE_CORNER_BL + DOUBLE_HORIZONTAL + cornerBR = DOUBLE_HORIZONTAL + DOUBLE_CORNER_BR + } + + // open side + BoxType.NORMAL_OPEN_SIDE -> { + vertical = SPACE + horizontal = NORMAL_HORIZONTAL + cornerTL = NORMAL_CORNER_TL + cornerTR = NORMAL_CORNER_TR + cornerBL = NORMAL_CORNER_BL + cornerBR = NORMAL_CORNER_BR + } + + BoxType.ROUNDED_OPEN_SIDE -> { + vertical = SPACE + horizontal = ROUNDED_HORIZONTAL + cornerTL = ROUNDED_CORNER_TL + cornerTR = ROUNDED_CORNER_TR + cornerBL = ROUNDED_CORNER_BL + cornerBR = ROUNDED_CORNER_BR + } + + BoxType.HEAVY_OPEN_SIDE -> { + vertical = SPACE + horizontal = HEAVY_HORIZONTAL + cornerTL = HEAVY_CORNER_TL + cornerTR = HEAVY_CORNER_TR + cornerBL = HEAVY_CORNER_BL + cornerBR = HEAVY_CORNER_BR + } + + BoxType.DOUBLE_OPEN_SIDE -> { + vertical = SPACE + horizontal = DOUBLE_HORIZONTAL + cornerTL = DOUBLE_CORNER_TL + cornerTR = DOUBLE_CORNER_TR + cornerBL = DOUBLE_CORNER_BL + cornerBR = DOUBLE_CORNER_BR + } } // ── Make Box ───────────────────────────────────────────────────────────────────────────────── - val lineStart = SPACE.repeat(indentLevel) + commentPrefix + SPACE.repeat(5) + val postCommentSymbolPadding = SPACE.repeat(settings.paddingSpaceAfterCommentSymbolBox) + val lineStart = SPACE.repeat(indentLevel) + commentPrefix + postCommentSymbolPadding val postCommentIndent = - if (commentSuffix.isNotEmpty()) SPACE.repeat(5) + commentSuffix else EMPTY + if (commentSuffix.isNotEmpty()) postCommentSymbolPadding + commentSuffix else EMPTY - val linePad = SPACE.repeat(2) - var fillLength = boxSettings.targetLength - (horizontal.length * 2) - (linePad.length * 2) + val linePad = SPACE.repeat(settings.paddingInsideBox) + var fillLength = settings.targetLengthBox - (horizontal.length * 2) - (linePad.length * 2) val box = buildString { val textList = - if (existingText.length >= boxSettings.targetLength || + if (existingText.length >= settings.targetLengthBox || existingText.contains("\n")) { buildList { fillLength = @@ -214,11 +362,11 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { max(acc, word.length) } val addLine = { line: String -> - add(line + " ".repeat(max(fillLength - line.length, 0))) + add(line + SPACE.repeat(max(fillLength - line.length, 0))) } existingText.split("\n").forEach { line -> var newLine = "" - line.split(" ").forEach { word -> + line.split(SPACE).forEach { word -> val tempLine = "$newLine $word".trim() if (tempLine.length > fillLength) { addLine(newLine) @@ -278,6 +426,7 @@ fun normalBox(e: AnActionEvent, boxType: BoxType, boxSettings: BoxSettings) { WriteCommandAction.runWriteCommandAction(e.project) { document.replaceString(startOffset, endOffset, box) } + // move caret to end of line - caretModel.moveToOffset(document.getLineEndOffset(caretModel.logicalPosition.line)) + caretModel.moveToOffset(startOffset + box.length) } diff --git a/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerLine.kt b/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerLine.kt index 0c042f5..14d61df 100644 --- a/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerLine.kt +++ b/src/main/kotlin/com/github/jdha/codedivider/action/CodeDividerLine.kt @@ -1,6 +1,9 @@ package com.github.jdha.codedivider.action -import com.github.jdha.codedivider.settings.* +import com.github.jdha.codedivider.settings.CodeDividerSettingsState +import com.github.jdha.codedivider.settings.CommentSymbolType +import com.github.jdha.codedivider.settings.TextCase +import com.github.jdha.codedivider.settings.TextPosition import com.intellij.lang.Commenter import com.intellij.lang.LanguageCommenters import com.intellij.openapi.actionSystem.AnAction @@ -9,70 +12,163 @@ import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.command.WriteCommandAction import java.util.* -// Examples +// ━━ SAMPLE LINES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // Normal Lines // ── Normal Left ────────────────────────────────────────────────────────────────────── // ─────────────────────────────────── Normal Center ─────────────────────────────────── -// ────────────────────────────────────────────────────────────────────── Normal Right── +// ───────────────────────────────────────────────────────────────────── Normal Right ── // Heavy Lines -// ══ HEAVY LEFT ═══════════════════════════════════════════════════════════════════════ -// ═══════════════════════════════════ HEAVY CENTER ════════════════════════════════════ -// ═══════════════════════════════════════════════════════════════════════ HEAVY RIGHT══ +// ━━ HEAVY LEFT ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ HEAVY CENTER ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ HEAVY RIGHT ━━ + +// Double Lines +// ══ Double Left ══════════════════════════════════════════════════════════════════════ +// ═══════════════════════════════════ Double Center ═══════════════════════════════════ +// ═════════════════════════════════════════════════════════════════════ Double Right ══ + +// ━━ CONSTANTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // General const val SPACE = " " const val EMPTY = "" -// ══ Normal ═══════════════════════════════════════════════════════════════════════════════════════ +// ━━ ACTIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -class CodeDividerLineTextLeftNormal : AnAction() { +// Standard +class CodeDividerLineTextLeftStandard : AnAction() { override fun actionPerformed(e: AnActionEvent) { - codeDivider(e, TextPosition.LEFT, CodeDividerSettingsState.instance.normalLineSettings) + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.LEFT, + lineCar = settings.lineCharStandard, + textCase = settings.textCaseStandard, + ) } } -class CodeDividerLineTextCenterNormal : AnAction() { +class CodeDividerLineTextCenterStandard : AnAction() { override fun actionPerformed(e: AnActionEvent) { - codeDivider(e, TextPosition.CENTER, CodeDividerSettingsState.instance.normalLineSettings) + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.CENTER, + lineCar = settings.lineCharStandard, + textCase = settings.textCaseStandard, + ) } } -class CodeDividerLineTextRightNormal : AnAction() { +class CodeDividerLineTextRightStandard : AnAction() { override fun actionPerformed(e: AnActionEvent) { - codeDivider(e, TextPosition.Right, CodeDividerSettingsState.instance.normalLineSettings) + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.Right, + lineCar = settings.lineCharStandard, + textCase = settings.textCaseStandard, + ) } } -// ══ Heavy ════════════════════════════════════════════════════════════════════════════════════════ - +// Heavy class CodeDividerLineTextLeftHeavy : AnAction() { override fun actionPerformed(e: AnActionEvent) { - codeDivider(e, TextPosition.LEFT, CodeDividerSettingsState.instance.heavyLineSettings) + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.LEFT, + lineCar = settings.lineCharHeavy, + textCase = settings.textCaseHeavy, + ) } } class CodeDividerLineTextCenterHeavy : AnAction() { override fun actionPerformed(e: AnActionEvent) { - codeDivider(e, TextPosition.CENTER, CodeDividerSettingsState.instance.heavyLineSettings) + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.CENTER, + lineCar = settings.lineCharHeavy, + textCase = settings.textCaseHeavy, + ) } } class CodeDividerLineTextRightHeavy : AnAction() { override fun actionPerformed(e: AnActionEvent) { - codeDivider(e, TextPosition.Right, CodeDividerSettingsState.instance.heavyLineSettings) + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.Right, + lineCar = settings.lineCharHeavy, + textCase = settings.textCaseHeavy, + ) } } -// ══ Logic ════════════════════════════════════════════════════════════════════════════════════════ +// Double +class CodeDividerLineTextLeftDouble : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.LEFT, + lineCar = settings.lineCharDouble, + textCase = settings.textCaseDouble, + ) + } +} -fun codeDivider(e: AnActionEvent, textPosition: TextPosition, lineSettings: LineSettings) { +class CodeDividerLineTextCenterDouble : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.CENTER, + lineCar = settings.lineCharDouble, + textCase = settings.textCaseDouble, + ) + } +} + +class CodeDividerLineTextRightDouble : AnAction() { + override fun actionPerformed(e: AnActionEvent) { + val settings = CodeDividerSettingsState.instance + codeDivider( + e = e, + settings = settings, + textPosition = TextPosition.Right, + lineCar = settings.lineCharDouble, + textCase = settings.textCaseDouble, + ) + } +} + +// ━━ LOGIC ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +fun codeDivider( + e: AnActionEvent, + settings: CodeDividerSettingsState, + textPosition: TextPosition, + lineCar: String, + textCase: TextCase +) { // ── Setup Values Needed To Make Line ───────────────────────────────────────────────────────── val editor = e.getData(CommonDataKeys.EDITOR) ?: return - // val settings = CodeDividerSettingsState.instance - val document = editor.document val caretModel = editor.caretModel val caretOffset = caretModel.offset @@ -85,15 +181,15 @@ fun codeDivider(e: AnActionEvent, textPosition: TextPosition, lineSettings: Line val language = e.getData(CommonDataKeys.PSI_FILE)?.language ?: return // ── Comment Symbols ────────────────────────────────────────────────────────────────────────── - val commentPad = if (lineSettings.whiteSpacePadCommentSymbol) SPACE else EMPTY + val commentPad = if (settings.whiteSpacePadCommentSymbolLine) SPACE else EMPTY val commenter = LanguageCommenters.INSTANCE.forLanguage(language) val (commentPrefix, commentSuffix) = getCommentSymbols( commenter = commenter, - errorOnNoCommentSymbol = lineSettings.whiteSpacePadCommentSymbol, + errorOnNoCommentSymbol = settings.errorOnNoCommentSymbol, commentPad = commentPad, - commentSymbolType = lineSettings.commentSymbolType, + commentSymbolType = settings.commentSymbolTypeLine, ) // ── Existing Text ──────────────────────────────────────────────────────────────────────────── @@ -105,9 +201,9 @@ fun codeDivider(e: AnActionEvent, textPosition: TextPosition, lineSettings: Line // ── Blank Line ─────────────────────────────────────────────────────────────────────────────── if (existingText.isBlank()) { - val remainingLength = lineSettings.lineLength - lineStart.length - commentSuffix.length + val remainingLength = settings.lineLengthLine - lineStart.length - commentSuffix.length if (remainingLength > 0) { - lineBody = lineSettings.customLineChar.repeat(remainingLength) + lineBody = lineCar.repeat(remainingLength) } WriteCommandAction.runWriteCommandAction(e.project) { val line = lineStart + lineBody + commentSuffix @@ -120,7 +216,7 @@ fun codeDivider(e: AnActionEvent, textPosition: TextPosition, lineSettings: Line // ── Not Blank Line ─────────────────────────────────────────────────────────────────────────── existingText = - when (lineSettings.textCase) { + when (textCase) { TextCase.UPPER -> existingText.uppercase() TextCase.LOWER -> existingText.lowercase() TextCase.TITLE -> @@ -135,39 +231,31 @@ fun codeDivider(e: AnActionEvent, textPosition: TextPosition, lineSettings: Line when (textPosition) { TextPosition.LEFT -> { - val prefixLineCharCount = if (lineSettings.whiteSpacePadCommentSymbol) 2 else 3 - lineBody = - lineSettings.customLineChar.repeat(prefixLineCharCount) + - SPACE + - existingText + - SPACE + val prefixLineCharCount = if (settings.whiteSpacePadCommentSymbolLine) 2 else 3 + lineBody = lineCar.repeat(prefixLineCharCount) + SPACE + existingText + SPACE val remainingLength = - lineSettings.lineLength - lineStart.length - lineBody.length - commentSuffix.length + settings.lineLengthLine - lineStart.length - lineBody.length - commentSuffix.length if (remainingLength > 0) { - lineBody += lineSettings.customLineChar.repeat(remainingLength) + lineBody += lineCar.repeat(remainingLength) } } TextPosition.CENTER -> { lineBody = SPACE + existingText + SPACE val remainingLength = - lineSettings.lineLength - lineStart.length - lineBody.length - commentSuffix.length + settings.lineLengthLine - lineStart.length - lineBody.length - commentSuffix.length if (remainingLength > 0) { val leftPadding = remainingLength / 2 val rightPadding = remainingLength - leftPadding - lineBody = - lineSettings.customLineChar.repeat(leftPadding) + - lineBody + - lineSettings.customLineChar.repeat(rightPadding) + lineBody = lineCar.repeat(leftPadding) + lineBody + lineCar.repeat(rightPadding) } } TextPosition.Right -> { - val suffixLineCharCount = if (lineSettings.whiteSpacePadCommentSymbol) 2 else 3 - lineBody = - SPACE + existingText + lineSettings.customLineChar.repeat(suffixLineCharCount) + val suffixLineCharCount = if (settings.whiteSpacePadCommentSymbolLine) 2 else 3 + lineBody = SPACE + existingText + SPACE + lineCar.repeat(suffixLineCharCount) val remainingLength = - lineSettings.lineLength - lineStart.length - lineBody.length - commentSuffix.length + settings.lineLengthLine - lineStart.length - lineBody.length - commentSuffix.length if (remainingLength > 0) { - lineBody = lineSettings.customLineChar.repeat(remainingLength) + lineBody + lineBody = lineCar.repeat(remainingLength) + lineBody } } } @@ -180,7 +268,7 @@ fun codeDivider(e: AnActionEvent, textPosition: TextPosition, lineSettings: Line caretModel.moveToOffset(document.getLineEndOffset(caretModel.logicalPosition.line)) } -// ══ HELPERS ══════════════════════════════════════════════════════════════════════════════════════ +// ━━ HELPERS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ fun getCommentSymbols( commenter: Commenter, diff --git a/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsConfigurable.kt b/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsConfigurable.kt index 783de8e..db4d5ed 100644 --- a/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsConfigurable.kt +++ b/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsConfigurable.kt @@ -12,31 +12,44 @@ class CodeDividerSettingsConfigurable : BoundConfigurable("Code Divider") { override fun createPanel(): DialogPanel { return panel { - // ══ LINE ═════════════════════════════════════════════════════════════════════════════ - collapsibleGroup("Code Divider - Line") { - // ── Normal Line ────────────────────────────────────────────────────────────── - group("Normal Line") { - row("Line length") { - spinner(40..300).bindIntValue(settings.normalLineSettings::lineLength) - } + // ━━ GENERAL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + collapsibleGroup("General") { + row("Error on no comment symbol for language") { + checkBox("").bindSelected(settings::errorOnNoCommentSymbol) + } + } + .expanded = true - row("Text case") { - comboBox(TextCase.values().asList()) - .bindItem( - settings.normalLineSettings::textCase.toNullableProperty()) - } + // ━━ LINE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + collapsibleGroup("Lines") { + // ── General ────────────────────────────────────────────────────────────────── + row("Line length") { spinner(40..300).bindIntValue(settings::lineLengthLine) } - row("Whitespace pad comment symbol") { - checkBox("") - .bindSelected( - settings.normalLineSettings::whiteSpacePadCommentSymbol) - } + row("Whitespace pad comment symbol") { + checkBox("").bindSelected(settings::whiteSpacePadCommentSymbolLine) + } - row("Error on no comment symbol for language") { - checkBox("") - .bindSelected(settings.normalLineSettings::errorOnNoCommentSymbol) + buttonsGroup(title = "Comment Symbol Type") { + row { + radioButton( + "Single line comment symbol, start only", + CommentSymbolType.ONE_SINGLE_LINE) + } + row { + radioButton( + "Single line comment symbol, start and end", + CommentSymbolType.TWO_SINGLE_LINE) + } + row { + radioButton( + "Multi line comment symbol, start and end", + CommentSymbolType.TWO_MULTI_LINE) + } } + .bind(settings::commentSymbolTypeLine) + // ── Standard Line ──────────────────────────────────────────────────────────── + group("Standard Line") { row("Custom line character") { comboBox(listOf("─")) .applyToComponent { @@ -51,56 +64,46 @@ class CodeDividerSettingsConfigurable : BoundConfigurable("Code Divider") { } }) } - .bindItem( - settings.normalLineSettings::customLineChar - .toNullableProperty()) + .bindItem(settings::lineCharStandard.toNullableProperty()) .columns(5) } - buttonsGroup(title = "Comment Symbol Type") { - row { - radioButton( - "Single line comment symbol, start only", - CommentSymbolType.ONE_SINGLE_LINE) - } - row { - radioButton( - "Single line comment symbol, start and end", - CommentSymbolType.TWO_SINGLE_LINE) - } - row { - radioButton( - "Multi line comment symbol, start and end", - CommentSymbolType.TWO_MULTI_LINE) - } - } - .bind(settings.normalLineSettings::commentSymbolType) + row("Text case transformation") { + comboBox(TextCase.values().asList()) + .bindItem(settings::textCaseStandard.toNullableProperty()) + } } // ── Heavy Line ─────────────────────────────────────────────────────────────── group("Heavy Line") { - row("Line length") { - spinner(40..300).bindIntValue(settings.heavyLineSettings::lineLength) + row("Custom line character") { + comboBox(listOf("━")) + .applyToComponent { + isEditable = true + editor.editorComponent.addKeyListener( + object : KeyAdapter() { + override fun keyTyped(e: KeyEvent) { + val textField = e.source as JTextField + if (textField.text.isNotEmpty()) { + e.consume() + } + } + }) + } + .bindItem(settings::lineCharHeavy.toNullableProperty()) + .columns(5) } - row("Text case") { + row("Text case transformation") { comboBox(TextCase.values().asList()) - .bindItem(settings.heavyLineSettings::textCase.toNullableProperty()) - } - - row("Whitespace pad comment symbol") { - checkBox("") - .bindSelected( - settings.heavyLineSettings::whiteSpacePadCommentSymbol) - } - - row("Error on no comment symbol for language") { - checkBox("") - .bindSelected(settings.heavyLineSettings::errorOnNoCommentSymbol) + .bindItem(settings::textCaseHeavy.toNullableProperty()) } + } + // ── Double Line ────────────────────────────────────────────────────────────── + group("Double Line") { row("Custom line character") { - comboBox(listOf("═", "━")) + comboBox(listOf("═")) .applyToComponent { isEditable = true editor.editorComponent.addKeyListener( @@ -113,41 +116,35 @@ class CodeDividerSettingsConfigurable : BoundConfigurable("Code Divider") { } }) } - .bindItem( - settings.heavyLineSettings::customLineChar.toNullableProperty()) + .bindItem(settings::lineCharDouble.toNullableProperty()) .columns(5) } - buttonsGroup(title = "Comment Symbol Type") { - row { - radioButton( - "Single line comment symbol, start only", - CommentSymbolType.ONE_SINGLE_LINE) - } - row { - radioButton( - "Single line comment symbol, start and end", - CommentSymbolType.TWO_SINGLE_LINE) - } - row { - radioButton( - "Multi line comment symbol, start and end", - CommentSymbolType.TWO_MULTI_LINE) - } - } - .bind(settings.heavyLineSettings::commentSymbolType) + row("Text case transformation") { + comboBox(TextCase.values().asList()) + .bindItem(settings::textCaseDouble.toNullableProperty()) + } } } .expanded = true - // ══ BOX ══════════════════════════════════════════════════════════════════════════════ - collapsibleGroup("Code Divider - Box") { - row("Box max length") { - spinner(40..300).bindIntValue(settings.boxSettings::maxLength) + // ━━ BOX ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + collapsibleGroup("Boxes") { + row("Box target length") { + spinner(40..300).bindIntValue(settings::targetLengthBox) + } + + row("Padding spaces after comment symbol") { + spinner(0..100).bindIntValue(settings::paddingSpaceAfterCommentSymbolBox) + } + + row("Padding inside box before and after text") { + spinner(0..100).bindIntValue(settings::paddingInsideBox) } - row("Target box length") { - spinner(40..300).bindIntValue(settings.boxSettings::targetLength) + row("Text case transformation") { + comboBox(TextCase.values().asList()) + .bindItem(settings::textCaseBox.toNullableProperty()) } } .expanded = true diff --git a/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsState.kt b/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsState.kt index 27d25de..08f5466 100644 --- a/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsState.kt +++ b/src/main/kotlin/com/github/jdha/codedivider/settings/CodeDividerSettingsState.kt @@ -5,16 +5,9 @@ import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.components.Service import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage -import com.intellij.util.xmlb.Converter import com.intellij.util.xmlb.XmlSerializerUtil -import com.intellij.util.xmlb.annotations.OptionTag -import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import org.jetbrains.annotations.NotNull import org.jetbrains.annotations.Nullable -@Serializable enum class TextCase { UPPER, LOWER, @@ -22,14 +15,12 @@ enum class TextCase { NONE } -@Serializable enum class TextPosition { LEFT, CENTER, Right } -@Serializable enum class CommentSymbolType { ONE_SINGLE_LINE, TWO_SINGLE_LINE, @@ -43,48 +34,43 @@ enum class BoxType { DOUBLE, NORMAL_OPEN_TOP, ROUNDED_OPEN_TOP, + HEAVY_OPEN_TOP, + DOUBLE_OPEN_TOP, + NORMAL_OPEN_SIDE, + ROUNDED_OPEN_SIDE, + HEAVY_OPEN_SIDE, + DOUBLE_OPEN_SIDE, } -@Serializable -enum class LineType { - NORMAL_LINE, - HEAVY_LINE, -} - -@Serializable -data class LineSettings( - var lineType: LineType, - var lineLength: Int, - var textCase: TextCase, - var whiteSpacePadCommentSymbol: Boolean, - var customLineChar: String, - var commentSymbolType: CommentSymbolType, - var errorOnNoCommentSymbol: Boolean -) - -@Serializable -data class BoxSettings( - var maxLength: Int, - var targetLength: Int, - var textCase: TextCase, - var commentSymbolType: CommentSymbolType, - var errorOnNoCommentSymbol: Boolean -) - @Service @State(name = "CodeDividerSettings", storages = [Storage("CodeDividerSettings.xml")]) class CodeDividerSettingsState : PersistentStateComponent { - // LINE - NORMAL - @OptionTag(converter = LineSettingsConverter::class) - var normalLineSettings = normalSettingDefaults() + // GENERAL + var errorOnNoCommentSymbol = true + + // LINE - GENERAL + var lineLengthLine = 88 + var whiteSpacePadCommentSymbolLine = true + var commentSymbolTypeLine = CommentSymbolType.ONE_SINGLE_LINE + + // LINE - STANDARD + var lineCharStandard = "─" + var textCaseStandard = TextCase.TITLE // LINE - HEAVY - @OptionTag(converter = LineSettingsConverter::class) - var heavyLineSettings = heavySettingDefaults() + var lineCharHeavy = "━" + var textCaseHeavy = TextCase.UPPER + + // LINE - DOUBLE + var lineCharDouble = "═" + var textCaseDouble = TextCase.TITLE // BOX - @OptionTag(converter = BoxSettingsConverter::class) var boxSettings = boxSettingDefaults() + var targetLengthBox = 60 + var paddingSpaceAfterCommentSymbolBox = 5 + var paddingInsideBox = 2 + var textCaseBox = TextCase.NONE companion object { val instance: CodeDividerSettingsState @@ -98,74 +84,3 @@ class CodeDividerSettingsState : PersistentStateComponent() { - override fun fromString(@NotNull value: String) = - try { - Json.decodeFromString(value) - } catch (e: Exception) { - println("Error encountered while deserializing JSON to LineSettings. Error: $e") - when { - value.contains(LineType.NORMAL_LINE.name) -> { - println("Setting default values for LineType.NORMAL_LINE") - normalSettingDefaults() - } - value.contains(LineType.HEAVY_LINE.name) -> { - println("Setting default values for LineType.HEAVY_LINE") - heavySettingDefaults() - } - else -> { - println("Could not find LineType reference. Setting value to normal default.") - normalSettingDefaults() - } - } - } - - override fun toString(value: LineSettings) = Json.encodeToString(value) -} - -class BoxSettingsConverter : Converter() { - override fun fromString(@NotNull value: String) = - try { - Json.decodeFromString(value) - } catch (e: Exception) { - println("Error encountered while deserializing JSON to BoxSettings. Error: $e") - println("Setting default values for Box Settings") - boxSettingDefaults() - } - - override fun toString(value: BoxSettings) = Json.encodeToString(value) -} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 17b3978..ecfe248 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -22,63 +22,193 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + +