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) + } + } + } + } + } +}