Skip to content

Instantly share code, notes, and snippets.

@dkandalov
Created May 26, 2025 15:48
Show Gist options
  • Save dkandalov/176103506770b8b12a9b67e006dd35bc to your computer and use it in GitHub Desktop.
Save dkandalov/176103506770b8b12a9b67e006dd35bc to your computer and use it in GitHub Desktop.
Mini plugin for IntelliJ to convert secondary constructor to top level function (basic implementations; to be used via LivePlugin)
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.util.parentOfType
import liveplugin.registerIntention
import org.jetbrains.kotlin.idea.base.util.reformatted
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
// depends-on-plugin org.jetbrains.kotlin
registerIntention(ConvertSecondaryConstructorToTopLevelFunction())
class ConvertSecondaryConstructorToTopLevelFunction : IntentionAction {
override fun isAvailable(project: Project, editor: Editor, file: PsiFile) =
currentElementIn(editor, file)?.parentOfType<KtSecondaryConstructor>() != null
override fun invoke(project: Project, editor: Editor, file: PsiFile) {
val constructor = currentElementIn(editor, file)?.parentOfType<KtSecondaryConstructor>() ?: return
val ktClass = constructor.parentOfType<KtClass>() ?: return
val factory = KtPsiFactory(project, false)
val function = factory.createFunction(
constructor.text
.replace("constructor", "fun ${ktClass.name}")
.replace(") :", ") =")
.replace("this", "${ktClass.name}")
)
val nextSibling = ktClass.prevSibling
val added = nextSibling.parent.addAfter(function, nextSibling).reformatted()
added.parent.addBefore(factory.createNewLine(2), added)
editor.caretModel.moveToOffset(added.textOffset - 1)
editor.scrollingModel.scrollToCaret(ScrollType.RELATIVE)
(constructor.nextSibling as? PsiWhiteSpace)?.delete()
constructor.delete()
}
fun currentElementIn(editor: Editor, file: PsiFile) =
file.findElementAt(editor.caretModel.offset)
override fun startInWriteAction() = true
override fun getText() = "Convert to top level function 🙈"
override fun getFamilyName() = "Live Plugin"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment