From ae55501210ff266f04a5cd071c4c449293d82d4d Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Thu, 10 Jun 2021 05:49:08 +0200 Subject: [PATCH 01/14] Make plugin compatible with idea version 2020.1 --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c5ab15b..918537e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official -pluginVersion = 1.0.0-193 -platformVersion = 2019.3 +pluginVersion = 1.0.0-201 +platformVersion = 2020.1 From 674aaf9f04e46d6947bd40704c58376dfb220d2c Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Thu, 10 Jun 2021 06:00:20 +0200 Subject: [PATCH 02/14] Make plugin compatible with idea version 2020.2 --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 918537e..f9509ff 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official -pluginVersion = 1.0.0-201 -platformVersion = 2020.1 +pluginVersion = 1.0.0-202 +platformVersion = 2020.2 From 5b2648f0c9ffecb694fa84b807c22bff703c9b4a Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Thu, 10 Jun 2021 06:08:15 +0200 Subject: [PATCH 03/14] Make plugin compatible with idea version 2020.3 --- gradle.properties | 4 ++-- .../filename_template/InitializeFilenameTemplateActivity.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index f9509ff..b2dc779 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official -pluginVersion = 1.0.0-202 -platformVersion = 2020.2 +pluginVersion = 1.0.0-203 +platformVersion = 2020.3 diff --git a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt index cf08a3b..0017705 100644 --- a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt +++ b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt @@ -19,7 +19,7 @@ class InitializeFilenameTemplateActivity : StartupActivity { val actionManager = ActionManager.getInstance() val newGroup = actionManager.getAction("NewGroup") as DefaultActionGroup - actionManager.getActionIds("FilenameTemplate").forEach { + actionManager.getActionIdList("FilenameTemplate").forEach { newGroup.remove(actionManager.getAction(it)) actionManager.unregisterAction(it) } From b1f1575809747fcd3775e2a5c83b01d04ecb84d2 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Thu, 10 Jun 2021 06:21:24 +0200 Subject: [PATCH 04/14] Make plugin compatible with idea version 2021.1 --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index b2dc779..0e3e96e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official -pluginVersion = 1.0.0-203 -platformVersion = 2020.3 +pluginVersion = 1.0.0-211 +platformVersion = 2021.1 From fe1b4db39a123ab248246844e7deb639551ae796 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sun, 24 Jan 2021 01:35:03 +0100 Subject: [PATCH 05/14] Refactor placeholder processing Iterate over the characters of the template string and process placeholders from left to right instead of replacing placeholders in an arbitrary order. The main benefit to this approach is avoiding regex to locate the placeholders. Finding the placeholders with regex is trickier than it looks like at first glance especially when nested placeholder boundary characters have to be considered. For example '{' and '}' are reserved date pattern characters which might be used within a date placeholder in the future. --- .../CreateFileWithFilenameTemplateAction.kt | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt index f7ea062..2e9cacf 100644 --- a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt +++ b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt @@ -14,6 +14,7 @@ import java.awt.event.InputEvent import java.time.LocalDateTime import java.time.ZoneOffset import java.util.function.Consumer +import kotlin.math.max class CreateFileWithFilenameTemplateAction( text: String, @@ -52,7 +53,47 @@ class CreateFileWithFilenameTemplateAction( } private fun processTemplate(template: String): String { - val epoch = LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC) - return template.replace("{EPOCH}", epoch.toString()) + var placeholderLevel = 0 + var placeholder = "" + var filename = "" + + for (character in template) { + when (character) { + '{' -> { + if (0 < placeholderLevel) { + placeholder += character + } + + placeholderLevel += 1 + } + '}' -> { + if (placeholderLevel == 1) { + filename += processPlaceholder(placeholder) + placeholder = "" + } + + placeholderLevel = max(0, placeholderLevel - 1) + + if (0 < placeholderLevel) { + placeholder += character + } + } + else -> { + if (0 < placeholderLevel) { + placeholder += character + } else { + filename += character + } + } + } + } + + return filename } + + private fun processPlaceholder(placeholder: String): String = + when (placeholder) { + "EPOCH" -> LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC).toString() + else -> "{$placeholder}" + } } From e5041d1822e6ff905a0a7d3231e17119ae1cf431 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sun, 24 Jan 2021 02:28:10 +0100 Subject: [PATCH 06/14] Extract placeholder processing --- .../CreateFileWithFilenameTemplateAction.kt | 54 ++---------------- .../InitializeFilenameTemplateActivity.kt | 10 +++- .../placeholders/DefaultPlaceholder.kt | 8 +++ .../placeholders/EpochPlaceholder.kt | 11 ++++ .../placeholders/Placeholder.kt | 6 ++ .../placeholders/PlaceholderContext.kt | 9 +++ .../placeholders/PlaceholderProcessor.kt | 56 +++++++++++++++++++ 7 files changed, 103 insertions(+), 51 deletions(-) create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/DefaultPlaceholder.kt create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/EpochPlaceholder.kt create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/Placeholder.kt create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt diff --git a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt index 2e9cacf..899f50c 100644 --- a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt +++ b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt @@ -10,16 +10,15 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.ui.InputValidatorEx import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiElement +import de.idetools.filename_template.placeholders.PlaceholderContext +import de.idetools.filename_template.placeholders.PlaceholderProcessor import java.awt.event.InputEvent -import java.time.LocalDateTime -import java.time.ZoneOffset import java.util.function.Consumer -import kotlin.math.max class CreateFileWithFilenameTemplateAction( text: String, description: String, - private val template: String + private val placeholderProcessor: PlaceholderProcessor ) : CreateFileAction(text, description, AllIcons.FileTypes.Unknown) { @@ -32,7 +31,7 @@ class CreateFileWithFilenameTemplateAction( val contentPanel = NewItemSimplePopupPanel() val nameField = contentPanel.textField - nameField.text = processTemplate(template) + nameField.text = placeholderProcessor.processTemplate(PlaceholderContext(project, directory)) val popup = NewItemPopupUtil.createNewItemPopup(IdeBundle.message("title.new.file"), contentPanel, nameField) contentPanel.setApplyAction { event: InputEvent? -> @@ -51,49 +50,4 @@ class CreateFileWithFilenameTemplateAction( } popup.showCenteredInCurrentWindow(project) } - - private fun processTemplate(template: String): String { - var placeholderLevel = 0 - var placeholder = "" - var filename = "" - - for (character in template) { - when (character) { - '{' -> { - if (0 < placeholderLevel) { - placeholder += character - } - - placeholderLevel += 1 - } - '}' -> { - if (placeholderLevel == 1) { - filename += processPlaceholder(placeholder) - placeholder = "" - } - - placeholderLevel = max(0, placeholderLevel - 1) - - if (0 < placeholderLevel) { - placeholder += character - } - } - else -> { - if (0 < placeholderLevel) { - placeholder += character - } else { - filename += character - } - } - } - } - - return filename - } - - private fun processPlaceholder(placeholder: String): String = - when (placeholder) { - "EPOCH" -> LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC).toString() - else -> "{$placeholder}" - } } diff --git a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt index 0017705..1072885 100644 --- a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt +++ b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt @@ -6,6 +6,9 @@ import com.intellij.openapi.actionSystem.Constraints import com.intellij.openapi.actionSystem.DefaultActionGroup import com.intellij.openapi.project.Project import com.intellij.openapi.startup.StartupActivity +import de.idetools.filename_template.placeholders.DefaultPlaceholder +import de.idetools.filename_template.placeholders.EpochPlaceholder +import de.idetools.filename_template.placeholders.PlaceholderProcessor import de.idetools.filename_template.settings.FilenameTemplateSettingsState class InitializeFilenameTemplateActivity : StartupActivity { @@ -16,6 +19,11 @@ class InitializeFilenameTemplateActivity : StartupActivity { internal fun initializeActions() { val settings: FilenameTemplateSettingsState = FilenameTemplateSettingsState.instance + val placeholders = listOf( + EpochPlaceholder(), + DefaultPlaceholder() + ) + val actionManager = ActionManager.getInstance() val newGroup = actionManager.getAction("NewGroup") as DefaultActionGroup @@ -29,7 +37,7 @@ class InitializeFilenameTemplateActivity : StartupActivity { val action = CreateFileWithFilenameTemplateAction( it.name, it.description, - it.template + PlaceholderProcessor(it.template, placeholders) ) val actionId = "FilenameTemplate.${it.name}" actionManager.registerAction(actionId, action) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/DefaultPlaceholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/DefaultPlaceholder.kt new file mode 100644 index 0000000..7493c80 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/DefaultPlaceholder.kt @@ -0,0 +1,8 @@ +package de.idetools.filename_template.placeholders + +class DefaultPlaceholder : Placeholder { + override fun supports(placeholder: String): Boolean = true + + override fun process(placeholder: String, context: PlaceholderContext): String = + "{$placeholder}" +} diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/EpochPlaceholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/EpochPlaceholder.kt new file mode 100644 index 0000000..f3f6fc0 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/EpochPlaceholder.kt @@ -0,0 +1,11 @@ +package de.idetools.filename_template.placeholders + +import java.time.LocalDateTime +import java.time.ZoneOffset + +class EpochPlaceholder : Placeholder { + override fun supports(placeholder: String): Boolean = placeholder == "EPOCH" + + override fun process(placeholder: String, context: PlaceholderContext): String = + LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC).toString() +} diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/Placeholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/Placeholder.kt new file mode 100644 index 0000000..4f34b74 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/Placeholder.kt @@ -0,0 +1,6 @@ +package de.idetools.filename_template.placeholders + +interface Placeholder { + fun supports(placeholder: String): Boolean + fun process(placeholder: String, context: PlaceholderContext): String +} diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt new file mode 100644 index 0000000..4bf2e1e --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt @@ -0,0 +1,9 @@ +package de.idetools.filename_template.placeholders + +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiDirectory + +data class PlaceholderContext( + val project: Project, + val directory: PsiDirectory +) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt new file mode 100644 index 0000000..5476c6c --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt @@ -0,0 +1,56 @@ +package de.idetools.filename_template.placeholders + +import java.util.function.Consumer +import kotlin.math.max + +class PlaceholderProcessor(private val template: String, private val placeholders: List) { + + fun processTemplate(placeholderContext: PlaceholderContext): String { + var filename = "" + processTemplate( + template, + { filename += it }, + { x -> + filename += placeholders + .first { it.supports(x) } + .process(x, placeholderContext) + }) + return filename + } + + private fun processTemplate(template: String, onCharacter: Consumer, onPlaceholder: Consumer) { + var placeholderLevel = 0 + var placeholder = "" + + for (character in template) { + when (character) { + '{' -> { + if (0 < placeholderLevel) { + placeholder += character + } + + placeholderLevel += 1 + } + '}' -> { + if (placeholderLevel == 1) { + onPlaceholder.accept(placeholder) + placeholder = "" + } + + placeholderLevel = max(0, placeholderLevel - 1) + + if (0 < placeholderLevel) { + placeholder += character + } + } + else -> { + if (0 < placeholderLevel) { + placeholder += character + } else { + onCharacter.accept(character) + } + } + } + } + } +} From 4b542a26774e9297bedd6ff922f40240e02d79a3 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sat, 23 Jan 2021 14:30:26 +0100 Subject: [PATCH 07/14] Add formatted date placeholder --- .../InitializeFilenameTemplateActivity.kt | 2 ++ .../placeholders/DatePlaceholder.kt | 20 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 6 ++++++ 3 files changed, 28 insertions(+) create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/DatePlaceholder.kt diff --git a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt index 1072885..e092f5f 100644 --- a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt +++ b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt @@ -6,6 +6,7 @@ import com.intellij.openapi.actionSystem.Constraints import com.intellij.openapi.actionSystem.DefaultActionGroup import com.intellij.openapi.project.Project import com.intellij.openapi.startup.StartupActivity +import de.idetools.filename_template.placeholders.DatePlaceholder import de.idetools.filename_template.placeholders.DefaultPlaceholder import de.idetools.filename_template.placeholders.EpochPlaceholder import de.idetools.filename_template.placeholders.PlaceholderProcessor @@ -21,6 +22,7 @@ class InitializeFilenameTemplateActivity : StartupActivity { val placeholders = listOf( EpochPlaceholder(), + DatePlaceholder(), DefaultPlaceholder() ) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/DatePlaceholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/DatePlaceholder.kt new file mode 100644 index 0000000..9c36484 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/DatePlaceholder.kt @@ -0,0 +1,20 @@ +package de.idetools.filename_template.placeholders + +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +class DatePlaceholder : Placeholder { + override fun supports(placeholder: String): Boolean = placeholder.startsWith("DATE") + + override fun process(placeholder: String, context: PlaceholderContext): String { + val date = LocalDateTime.now() + val datePattern = placeholder.substringAfter(":", "") + val formatter = + if (datePattern.isBlank()) { + DateTimeFormatter.ISO_DATE + } else { + DateTimeFormatter.ofPattern(datePattern) + } + return date.format(formatter) + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index d9fdc38..5c8a3f0 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,12 @@

A template might contain following place holders:

+
{DATE:FORMAT}
+
+ The formatted date. If the format is omitted "yyyy-MM-dd" is used by default.
+ See the java documentation for supported patterns: Patterns for Formatting and Parsing +
+
{EPOCH}
The current unix time stamp: Seconds since the Unix Epoch on January 1st, 1970 at UTC.
From fc81383e1ff5fbf86084aa115f70ff36e30aab2b Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sat, 23 Jan 2021 14:42:25 +0100 Subject: [PATCH 08/14] Add project name placeholder --- .../InitializeFilenameTemplateActivity.kt | 2 ++ .../filename_template/placeholders/ProjectPlaceholder.kt | 8 ++++++++ src/main/resources/META-INF/plugin.xml | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/ProjectPlaceholder.kt diff --git a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt index e092f5f..ffc2de5 100644 --- a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt +++ b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt @@ -10,6 +10,7 @@ import de.idetools.filename_template.placeholders.DatePlaceholder import de.idetools.filename_template.placeholders.DefaultPlaceholder import de.idetools.filename_template.placeholders.EpochPlaceholder import de.idetools.filename_template.placeholders.PlaceholderProcessor +import de.idetools.filename_template.placeholders.ProjectPlaceholder import de.idetools.filename_template.settings.FilenameTemplateSettingsState class InitializeFilenameTemplateActivity : StartupActivity { @@ -23,6 +24,7 @@ class InitializeFilenameTemplateActivity : StartupActivity { val placeholders = listOf( EpochPlaceholder(), DatePlaceholder(), + ProjectPlaceholder(), DefaultPlaceholder() ) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/ProjectPlaceholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/ProjectPlaceholder.kt new file mode 100644 index 0000000..03912ac --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/ProjectPlaceholder.kt @@ -0,0 +1,8 @@ +package de.idetools.filename_template.placeholders + +class ProjectPlaceholder : Placeholder { + override fun supports(placeholder: String): Boolean = placeholder == "PROJECT" + + override fun process(placeholder: String, context: PlaceholderContext): String = + context.project.name +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 5c8a3f0..3b15ced 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -43,6 +43,11 @@
{EPOCH}
The current unix time stamp: Seconds since the Unix Epoch on January 1st, 1970 at UTC.
+ +
{PROJECT}
+
+ The name of the current project. +
From 869eb2cbc7d35c62f9d25da46cf477684ebcffb6 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sat, 23 Jan 2021 15:15:23 +0100 Subject: [PATCH 09/14] Add hostname placeholder --- .../InitializeFilenameTemplateActivity.kt | 2 ++ .../filename_template/placeholders/HostPlaceholder.kt | 10 ++++++++++ src/main/resources/META-INF/plugin.xml | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/HostPlaceholder.kt diff --git a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt index ffc2de5..c35d83d 100644 --- a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt +++ b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.startup.StartupActivity import de.idetools.filename_template.placeholders.DatePlaceholder import de.idetools.filename_template.placeholders.DefaultPlaceholder import de.idetools.filename_template.placeholders.EpochPlaceholder +import de.idetools.filename_template.placeholders.HostPlaceholder import de.idetools.filename_template.placeholders.PlaceholderProcessor import de.idetools.filename_template.placeholders.ProjectPlaceholder import de.idetools.filename_template.settings.FilenameTemplateSettingsState @@ -25,6 +26,7 @@ class InitializeFilenameTemplateActivity : StartupActivity { EpochPlaceholder(), DatePlaceholder(), ProjectPlaceholder(), + HostPlaceholder(), DefaultPlaceholder() ) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/HostPlaceholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/HostPlaceholder.kt new file mode 100644 index 0000000..33f2ca8 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/HostPlaceholder.kt @@ -0,0 +1,10 @@ +package de.idetools.filename_template.placeholders + +import java.net.InetAddress + +class HostPlaceholder : Placeholder { + override fun supports(placeholder: String): Boolean = placeholder == "HOST" + + override fun process(placeholder: String, context: PlaceholderContext): String = + InetAddress.getLocalHost().hostName +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 3b15ced..43da782 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -44,6 +44,11 @@
{EPOCH}
The current unix time stamp: Seconds since the Unix Epoch on January 1st, 1970 at UTC.
+
{HOST}
+
+ The computers hostname. +
+
{PROJECT}
The name of the current project. From b8bea349ba7f7419d11c085e7058b035bcb2875a Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sat, 23 Jan 2021 15:19:43 +0100 Subject: [PATCH 10/14] Add username placeholder --- .../InitializeFilenameTemplateActivity.kt | 2 ++ .../filename_template/placeholders/UserPlaceholder.kt | 8 ++++++++ src/main/resources/META-INF/plugin.xml | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/UserPlaceholder.kt diff --git a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt index c35d83d..c3cfa14 100644 --- a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt +++ b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt @@ -12,6 +12,7 @@ import de.idetools.filename_template.placeholders.EpochPlaceholder import de.idetools.filename_template.placeholders.HostPlaceholder import de.idetools.filename_template.placeholders.PlaceholderProcessor import de.idetools.filename_template.placeholders.ProjectPlaceholder +import de.idetools.filename_template.placeholders.UserPlaceholder import de.idetools.filename_template.settings.FilenameTemplateSettingsState class InitializeFilenameTemplateActivity : StartupActivity { @@ -27,6 +28,7 @@ class InitializeFilenameTemplateActivity : StartupActivity { DatePlaceholder(), ProjectPlaceholder(), HostPlaceholder(), + UserPlaceholder(), DefaultPlaceholder() ) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/UserPlaceholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/UserPlaceholder.kt new file mode 100644 index 0000000..32a41d2 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/UserPlaceholder.kt @@ -0,0 +1,8 @@ +package de.idetools.filename_template.placeholders + +class UserPlaceholder : Placeholder { + override fun supports(placeholder: String): Boolean = placeholder == "USER" + + override fun process(placeholder: String, context: PlaceholderContext): String = + System.getProperty("user.name") +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 43da782..79b59d3 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -53,6 +53,11 @@
The name of the current project.
+ +
{USER}
+
+ The username of the user running the IDE. +
From 72956bfd58f8b1095be88315ad1865a85228184d Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sun, 20 Jun 2021 05:46:58 +0200 Subject: [PATCH 11/14] Make current filename accessible to placeholders --- .../CreateFileWithFilenameTemplateAction.kt | 3 +- .../placeholders/PlaceholderContext.kt | 3 +- .../placeholders/PlaceholderProcessor.kt | 28 ++++++++----------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt index 899f50c..310ae8c 100644 --- a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt +++ b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt @@ -10,7 +10,6 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.ui.InputValidatorEx import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiElement -import de.idetools.filename_template.placeholders.PlaceholderContext import de.idetools.filename_template.placeholders.PlaceholderProcessor import java.awt.event.InputEvent import java.util.function.Consumer @@ -31,7 +30,7 @@ class CreateFileWithFilenameTemplateAction( val contentPanel = NewItemSimplePopupPanel() val nameField = contentPanel.textField - nameField.text = placeholderProcessor.processTemplate(PlaceholderContext(project, directory)) + nameField.text = placeholderProcessor.processTemplate(project, directory) val popup = NewItemPopupUtil.createNewItemPopup(IdeBundle.message("title.new.file"), contentPanel, nameField) contentPanel.setApplyAction { event: InputEvent? -> diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt index 4bf2e1e..177db24 100644 --- a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderContext.kt @@ -5,5 +5,6 @@ import com.intellij.psi.PsiDirectory data class PlaceholderContext( val project: Project, - val directory: PsiDirectory + val directory: PsiDirectory, + var filename: String = "" ) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt index 5476c6c..f521fc3 100644 --- a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt @@ -1,27 +1,17 @@ package de.idetools.filename_template.placeholders -import java.util.function.Consumer +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiDirectory import kotlin.math.max class PlaceholderProcessor(private val template: String, private val placeholders: List) { - fun processTemplate(placeholderContext: PlaceholderContext): String { - var filename = "" - processTemplate( - template, - { filename += it }, - { x -> - filename += placeholders - .first { it.supports(x) } - .process(x, placeholderContext) - }) - return filename - } - - private fun processTemplate(template: String, onCharacter: Consumer, onPlaceholder: Consumer) { + fun processTemplate(project: Project, directory: PsiDirectory): String { var placeholderLevel = 0 var placeholder = "" + val context = PlaceholderContext(project, directory) + for (character in template) { when (character) { '{' -> { @@ -33,7 +23,9 @@ class PlaceholderProcessor(private val template: String, private val placeholder } '}' -> { if (placeholderLevel == 1) { - onPlaceholder.accept(placeholder) + context.filename += placeholders + .first { it.supports(placeholder) } + .process(placeholder, context) placeholder = "" } @@ -47,10 +39,12 @@ class PlaceholderProcessor(private val template: String, private val placeholder if (0 < placeholderLevel) { placeholder += character } else { - onCharacter.accept(character) + context.filename += character } } } } + + return context.filename } } From d72198746f9f3daa7438df75989076dc8882b6a4 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sat, 23 Jan 2021 15:09:36 +0100 Subject: [PATCH 12/14] Add sequence placeholder --- .../InitializeFilenameTemplateActivity.kt | 2 ++ .../placeholders/SequencePlaceholder.kt | 22 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 6 +++++ 3 files changed, 30 insertions(+) create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/SequencePlaceholder.kt diff --git a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt index c3cfa14..e224f9e 100644 --- a/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt +++ b/src/main/kotlin/de/idetools/filename_template/InitializeFilenameTemplateActivity.kt @@ -12,6 +12,7 @@ import de.idetools.filename_template.placeholders.EpochPlaceholder import de.idetools.filename_template.placeholders.HostPlaceholder import de.idetools.filename_template.placeholders.PlaceholderProcessor import de.idetools.filename_template.placeholders.ProjectPlaceholder +import de.idetools.filename_template.placeholders.SequencePlaceholder import de.idetools.filename_template.placeholders.UserPlaceholder import de.idetools.filename_template.settings.FilenameTemplateSettingsState @@ -28,6 +29,7 @@ class InitializeFilenameTemplateActivity : StartupActivity { DatePlaceholder(), ProjectPlaceholder(), HostPlaceholder(), + SequencePlaceholder(), UserPlaceholder(), DefaultPlaceholder() ) diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/SequencePlaceholder.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/SequencePlaceholder.kt new file mode 100644 index 0000000..bcb9707 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/SequencePlaceholder.kt @@ -0,0 +1,22 @@ +package de.idetools.filename_template.placeholders + +import com.intellij.psi.PsiFile + +class SequencePlaceholder : Placeholder { + override fun supports(placeholder: String): Boolean = placeholder.matches("^\\d+$".toRegex()) + + override fun process(placeholder: String, context: PlaceholderContext): String { + var value = Integer.parseInt(placeholder) + while (sequenceValueExists(context.directory.files, context.filename + formatSequence(value, placeholder.length))) { + value++ + } + return formatSequence(value, placeholder.length) + } + + private fun sequenceValueExists(files: Array, sequence: String): Boolean { + return files.any { it.name.startsWith(sequence) } + } + + private fun formatSequence(value: Int, length: Int) = + value.toString().padStart(length, '0') +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 79b59d3..59f1874 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -58,6 +58,12 @@
The username of the user running the IDE.
+ +
{###}
+
+ The first available sequential number. Define the initial value and desired leading zeros in the template. + Example: notes({042}).md => notes(042).md, notes(043).md, ... +
From e7f3c6f80e359319f4222b0d38cf44f583db1578 Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sun, 20 Jun 2021 09:45:50 +0200 Subject: [PATCH 13/14] Add caret position placeholder --- .../CreateFileWithFilenameTemplateAction.kt | 5 ++++- .../placeholders/PlaceholderProcessor.kt | 11 +++++++++-- .../placeholders/ProcessedTemplate.kt | 6 ++++++ src/main/resources/META-INF/plugin.xml | 3 +++ 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/de/idetools/filename_template/placeholders/ProcessedTemplate.kt diff --git a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt index 310ae8c..ffd4063 100644 --- a/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt +++ b/src/main/kotlin/de/idetools/filename_template/CreateFileWithFilenameTemplateAction.kt @@ -30,7 +30,10 @@ class CreateFileWithFilenameTemplateAction( val contentPanel = NewItemSimplePopupPanel() val nameField = contentPanel.textField - nameField.text = placeholderProcessor.processTemplate(project, directory) + val (filename, caretPosition) = placeholderProcessor.processTemplate(project, directory) + + nameField.text = filename + nameField.caretPosition = caretPosition val popup = NewItemPopupUtil.createNewItemPopup(IdeBundle.message("title.new.file"), contentPanel, nameField) contentPanel.setApplyAction { event: InputEvent? -> diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt index f521fc3..1768331 100644 --- a/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/PlaceholderProcessor.kt @@ -6,7 +6,7 @@ import kotlin.math.max class PlaceholderProcessor(private val template: String, private val placeholders: List) { - fun processTemplate(project: Project, directory: PsiDirectory): String { + fun processTemplate(project: Project, directory: PsiDirectory): ProcessedTemplate { var placeholderLevel = 0 var placeholder = "" @@ -45,6 +45,13 @@ class PlaceholderProcessor(private val template: String, private val placeholder } } - return context.filename + val caretPosition = when { + context.filename.indexOf("{|}") != -1 -> context.filename.indexOf("{|}") + context.filename.indexOfFirst { it == '.' } != -1 -> context.filename.indexOfFirst { it == '.' } + else -> context.filename.length + } + context.filename = context.filename.replace("{|}", "") + + return ProcessedTemplate(context.filename, caretPosition) } } diff --git a/src/main/kotlin/de/idetools/filename_template/placeholders/ProcessedTemplate.kt b/src/main/kotlin/de/idetools/filename_template/placeholders/ProcessedTemplate.kt new file mode 100644 index 0000000..3673772 --- /dev/null +++ b/src/main/kotlin/de/idetools/filename_template/placeholders/ProcessedTemplate.kt @@ -0,0 +1,6 @@ +package de.idetools.filename_template.placeholders + +data class ProcessedTemplate( + val filename: String, + val caretPosition: Int +) diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 59f1874..5e0e4b0 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -64,6 +64,9 @@ The first available sequential number. Define the initial value and desired leading zeros in the template. Example: notes({042}).md => notes(042).md, notes(043).md, ... + +
{|}
+
The caret position. If omitted the caret is positioned before the first '.' if available or at the end.
From 543435b7a04d55723b2e217b3066b59ad509b98c Mon Sep 17 00:00:00 2001 From: Matthias Gugel Date: Sun, 24 Jan 2021 09:51:00 +0100 Subject: [PATCH 14/14] Update version and release notes --- build.gradle.kts | 6 ++++++ gradle.properties | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 53a305f..9997964 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,6 +23,12 @@ intellij { } tasks.getByName("patchPluginXml") { changeNotes(""" +

[1.1]

+ +
    +
  • Placeholders for: date, hostname, project name, username, sequential numbers, and caret position
  • +
+

[1.0]

    diff --git a/gradle.properties b/gradle.properties index 0e3e96e..c7b76fe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official -pluginVersion = 1.0.0-211 +pluginVersion = 1.1.0-211 platformVersion = 2021.1