/live-plugin

IntelliJ plugin for writing plugins at runtime

Primary LanguageJavaOtherNOASSERTION

toolwindow

What is this?

This is IntelliJ plugin for writing IDE plugins at runtime (or running any code inside IntelliJ). It uses Groovy as a main language and has experimental support for Scala and Clojure.

Why?

It's difficult to explain better than Martin Fowler does in this post but in short:

  • to make writing plugins easier. There is no need to set up and configure a separate project.
  • faster feedback loop. There is no need to start new IDE instance to run a plugin. If you change plugin code, there is no need to restart IDE.
  • great goodness of customized IDE. In a way even Excel can be "customized" at runtime with VB script. This is an attempt to fix this and have easy-to-extend IDE.

Example plugin

import com.intellij.openapi.actionSystem.AnActionEvent
import static liveplugin.PluginUtil.*

// This action inserts new line above current line.
// It's a follow-up for these posts:
//   http://martinfowler.com/bliki/InternalReprogrammability.html
//   http://nealford.com/memeagora/2013/01/22/why_everyone_eventually_hates_maven.html
// Note that there is "Start New Line Before Current" action (ctrl + alt + enter) which does almost the same thing.

registerAction("InsertNewLineAbove", "alt shift ENTER") { AnActionEvent event ->
	runDocumentWriteAction(event.project) {
		currentEditorIn(event.project).with {
			def offset = caretModel.offset
			def currentLine = caretModel.logicalPosition.line
			def lineStartOffset = document.getLineStartOffset(currentLine)

			document.insertString(lineStartOffset, "\n")
			caretModel.moveToOffset(offset + 1)
		}
	}
}
show("Loaded 'InsertNewLineAbove' action<br/>Use 'Alt+Shift+Enter' to run it")

See also Scala plugin example and Clojure plugin example.

How to install

Through IntelliJ plugin manager. Search for "liveplugin". (Just in case this is the plugin page.)

How to start

  • open "Plugins" tool window on the right side
  • select "helloWorld" plugin and press "alt + C, alt + E" to execute it ("plugin.groovy" are plugin entry points)
  • add plugin examples and experiment with them

"Advanced" usage

  • it helps to have JetGroovy plugin installed (available only for IntelliJ IDEA)
  • you can get auto-completion in plugins code by adding IDEA and LivePlugin jars to project (in "Settings" drop-down at the top of "Plugins" tool window).
  • check PluginUtil class. Even if you don't want to use it, it might be a good place to see how to interact with IntelliJ API.
  • get IntelliJ source code, look at how some feature is implemented, steal the code

More examples

How this plugin works?

It just evaluates code inside JVM, like this:

GroovyScriptEngine scriptEngine = new GroovyScriptEngine(pluginFolderUrl, classLoader);
scriptEngine.run(mainScriptUrl, createGroovyBinding(binding));
  • each plugin is evaluated with its own classloader
  • it uses Groovy bundled with IntelliJ
  • plugins are stored in "$HOME/.$INTELLIJ_VERSION/config/live-plugins" (on Mac "$HOME/Library/Application Support/IntelliJIdea12/live-plugins"). You can also use standard "ctrl + shift + C" shortcut to copy file/folder path.

Similar plugins

The idea of running code inside IntelliJ is not original. There are similar plugins (although I wasn't too happy with them):

It would be interesting

  • try writing a language plugin
  • to have nice object tree pattern-matching API for Groovy (can be good for writing inspections/intentions to match/replace syntax tree).
  • more languages, e.g. Ruby, Kotlin or Java.

If you want to contribute

That's great! But please be aware this is a proof-of-concept project, don't expect to see great code. I could write a blog post about extendable IDEs but probably not many people would read it so this is kind of "blog with working code" approach.

  • use download_libs.rb to get dependencies
  • open project in IntelliJ IDEA (you probably will have to configure IntelliJ SDK)
  • packages are structured in attempt to reflect plugins toolwindow UI