Extract placeholder processing

This commit is contained in:
Matthias Gugel 2021-01-24 02:28:10 +01:00
parent fe1b4db39a
commit e5041d1822
7 changed files with 103 additions and 51 deletions

View File

@ -10,16 +10,15 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.InputValidatorEx import com.intellij.openapi.ui.InputValidatorEx
import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiElement 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.awt.event.InputEvent
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.util.function.Consumer import java.util.function.Consumer
import kotlin.math.max
class CreateFileWithFilenameTemplateAction( class CreateFileWithFilenameTemplateAction(
text: String, text: String,
description: String, description: String,
private val template: String private val placeholderProcessor: PlaceholderProcessor
) : ) :
CreateFileAction(text, description, AllIcons.FileTypes.Unknown) { CreateFileAction(text, description, AllIcons.FileTypes.Unknown) {
@ -32,7 +31,7 @@ class CreateFileWithFilenameTemplateAction(
val contentPanel = NewItemSimplePopupPanel() val contentPanel = NewItemSimplePopupPanel()
val nameField = contentPanel.textField 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) val popup = NewItemPopupUtil.createNewItemPopup(IdeBundle.message("title.new.file"), contentPanel, nameField)
contentPanel.setApplyAction { event: InputEvent? -> contentPanel.setApplyAction { event: InputEvent? ->
@ -51,49 +50,4 @@ class CreateFileWithFilenameTemplateAction(
} }
popup.showCenteredInCurrentWindow(project) 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}"
}
} }

View File

@ -6,6 +6,9 @@ import com.intellij.openapi.actionSystem.Constraints
import com.intellij.openapi.actionSystem.DefaultActionGroup import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupActivity 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 import de.idetools.filename_template.settings.FilenameTemplateSettingsState
class InitializeFilenameTemplateActivity : StartupActivity { class InitializeFilenameTemplateActivity : StartupActivity {
@ -16,6 +19,11 @@ class InitializeFilenameTemplateActivity : StartupActivity {
internal fun initializeActions() { internal fun initializeActions() {
val settings: FilenameTemplateSettingsState = FilenameTemplateSettingsState.instance val settings: FilenameTemplateSettingsState = FilenameTemplateSettingsState.instance
val placeholders = listOf(
EpochPlaceholder(),
DefaultPlaceholder()
)
val actionManager = ActionManager.getInstance() val actionManager = ActionManager.getInstance()
val newGroup = actionManager.getAction("NewGroup") as DefaultActionGroup val newGroup = actionManager.getAction("NewGroup") as DefaultActionGroup
@ -29,7 +37,7 @@ class InitializeFilenameTemplateActivity : StartupActivity {
val action = CreateFileWithFilenameTemplateAction( val action = CreateFileWithFilenameTemplateAction(
it.name, it.name,
it.description, it.description,
it.template PlaceholderProcessor(it.template, placeholders)
) )
val actionId = "FilenameTemplate.${it.name}" val actionId = "FilenameTemplate.${it.name}"
actionManager.registerAction(actionId, action) actionManager.registerAction(actionId, action)

View File

@ -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}"
}

View File

@ -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()
}

View File

@ -0,0 +1,6 @@
package de.idetools.filename_template.placeholders
interface Placeholder {
fun supports(placeholder: String): Boolean
fun process(placeholder: String, context: PlaceholderContext): String
}

View File

@ -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
)

View File

@ -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<Placeholder>) {
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<Char>, onPlaceholder: Consumer<String>) {
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)
}
}
}
}
}
}