Skip to content

The Event System

Xed-Editor uses a powerful event system to let extensions respond to what is happening in the app. You can listen for existing events or even create and publish your own.

Subscribing to Events

To listen for an event, use Events.subscribe. You specify the type of event you want to hear.

kotlin
val subscription = Events.subscribe<TabEvent.Opened> { event ->
    context.logInfo("A new tab was opened: ${event.tab.title}")
}

Unsubscribing

Always unregister your listeners when they are no longer needed. The subscribe method returns a subscription object that you can use to stop listening.

kotlin
override fun onDispose() {
    subscription.unsubscribe()
}

Editor Events

Events related to the editor view are handled slightly differently, because they are managed by a library we are using: sora-editor.

First, you listen for a new editor instance being created, and then you subscribe to that specific instance.

kotlin
val editorSubscriptions = mutableListOf<SubscriptionReceipt<*>>()

val subscription =
    Events.subscribe<EditorEvent.InstanceCreated> { event ->
        val editor = event.editor

        // Listen to events on this specific editor
        editorSubscriptions.add(
            editor.subscribeAlways<ContentChangeEvent> { editorEvent ->
                println("Text changed: ${editorEvent.changedText}")
            }
        )
    }

As you can see, you should always store the subscriptions in variables to be able to unsubscribe later when they're no longer needed:

kotlin
override fun onDispose() {
    subscription.unsubscribe()
    editorSubscriptions.forEach { it.unsubscribe() }
}

Event Inheritance

Events support inheritance, allowing you to subscribe to a whole category of events instead of individual event types.

For example, subscribing to FileEvent receives all file-related events:

kotlin
Events.subscribe<FileEvent> { event ->
    // Receives Created, Deleted, Renamed, Moved and Copied
}

You could theoretically also subscribe to the base Event type to receive every event.

List of Events

Here is a list of almost all events you can listen for:

Drawer Events

EventWhen it happens
DrawerEvent.TabAddedA drawer tab is added.
DrawerEvent.TabRemovedA drawer tab is removed.
DrawerEvent.TabSelectedThe active drawer tab changes.
DrawerEvent.ServicesInitializedService tabs are initialized.
DrawerEvent.ServiceTabSelectedThe active service tab changes.

File Tree Events

EventWhen it happens
FileTreeEvent.OpenedA file tree drawer is opened.
FileTreeEvent.ClosedA file tree drawer is closed.
FileTreeEvent.NodeExpandedA folder is expanded.
FileTreeEvent.NodeCollapsedA folder is collapsed.
FileTreeEvent.FocusedA file tree node gains focus.
FileTreeEvent.SelectionChangedThe file tree selection changes.
FileTreeEvent.TreeSynchronizedThe file tree is synchronized with file system (after file creation, refresh, ...).

File Events

EventWhen it happens
FileEvent.CreatedA file or directory is created.
FileEvent.DeletedA file or directory is deleted.
FileEvent.RenamedA file or directory is renamed.
FileEvent.MovedA file or directory is moved.
FileEvent.CopiedA file or directory is copied.

Tab Events

General Tabs

EventWhen it happens
TabEvent.OpenedA tab is opened.
TabEvent.ClosedA tab is closed.
TabEvent.SelectedA tab is selected.
TabEvent.ReorderedTabs are reordered.

Editor Tabs

EventWhen it happens
EditorTabEvent.OpenedAn editor tab is opened.
EditorTabEvent.ClosedAn editor tab is closed.
EditorTabEvent.SelectedAn editor tab is selected.
EditorTabEvent.ReorderedEditor tabs are reordered.
EditorTabEvent.RefreshedAn editor tab is refreshed.
EditorTabEvent.SavedAn editor tab is saved.

Editor Events

EventWhen it happens
EditorEvent.InstanceCreatedA new editor is created.
EditorEvent.InstanceDestroyedAn editor is destroyed.

Language Server Events

EventWhen it happens
LSPEvent.InstanceCreatedAn LSP instance is created.
LSPEvent.StatusChangedAn LSP connection status changes.
LSPEvent.LogEntryWrittenAn LSP writes a log entry.
LSPEvent.ConnectionCompletedLSP connection finishes for a file.

Application Events

EventWhen it happens
AppEvent.ThemeChangedThe app theme changes.
AppEvent.IconPackChangedThe icon pack changes.
AppEvent.LanguageChangedThe app language changes.
AppEvent.LogEntryWrittenThe app writes a log entry.

Extension Events

EventWhen it happens
ExtensionEvent.InstalledAn extension is installed.
ExtensionEvent.LoadedAn extension is loaded.
ExtensionEvent.CrashedAn extension crashes.
ExtensionEvent.UninstalledAn extension is uninstalled.

Git Events

EventWhen it happens
GitEvent.RepositoryInitializedA repository is initialized.
GitEvent.RepositoryClonedA repository is cloned.
GitEvent.BranchCreatedA branch is created.
GitEvent.BranchDeletedA branch is deleted.
GitEvent.BranchCheckedOutA branch is checked out.
GitEvent.BranchRenamedA branch is renamed.
GitEvent.MergedA branch is merged.
GitEvent.RebasedA branch is rebased.
GitEvent.CommitCreatedA commit is created.
GitEvent.CommitAmendedA commit is amended.
GitEvent.FetchCompletedA fetch completes.
GitEvent.PullCompletedA pull completes.
GitEvent.PushCompletedA push completes.
GitEvent.WorkingTreeUpdatedThe working tree changes.

Runner Events

EventWhen it happens
RunnerEvent.RunnerRunA runner is started.

Custom Events

You can also create your own events to communicate between different parts of your extension or even with other extensions (dependants).

  1. Define your event class:
kotlin
data class MyCustomEvent(val message: String) : Event
  1. Publish the event:
kotlin
Events.publish(MyCustomEvent("Hello World!"))
  1. Subscribe to it elsewhere:
kotlin
Events.subscribe<MyCustomEvent> { event ->
    context.logInfo("Received: ${event.message}")
}

This is a great way to keep your extension's components decoupled and easy to manage.