Skip to content

Commit

Permalink
add websocket loop with source
Browse files Browse the repository at this point in the history
  • Loading branch information
ummcheng committed Jul 31, 2020
1 parent 24a69fa commit 6343d03
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.gradle
.idea
build
out
9 changes: 7 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ plugins {
id("org.jetbrains.changelog") version "0.4.0"
// detekt linter - read more: https://detekt.github.io/detekt/kotlindsl.html
id("io.gitlab.arturbosch.detekt") version "1.10.0"
// ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
// ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradleg
id("org.jlleitschuh.gradle.ktlint") version "9.2.1"
}

Expand All @@ -31,6 +31,7 @@ val platformDownloadSources: String by project

group = pluginGroup
version = pluginVersion
val ktor_version = "1.3.2"

// Configure project's dependencies
repositories {
Expand All @@ -40,6 +41,11 @@ repositories {
dependencies {
implementation(kotlin("stdlib-jdk8"))
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.10.0")
implementation("io.ktor:ktor-client-websockets:$ktor_version")
implementation("io.ktor:ktor-client-cio:$ktor_version")
implementation("io.ktor:ktor-client-js:$ktor_version")
implementation("io.ktor:ktor-client-okhttp:$ktor_version")
implementation("com.google.code.gson:gson:2.8.5")
}

// Configure gradle-intellij-plugin plugin.
Expand All @@ -53,7 +59,6 @@ intellij {

// Plugin Dependencies:
// https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_dependencies.html
//
setPlugins("java")
}

Expand Down
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
pluginGroup = ai.serenade.intellij
pluginName = Serenade
pluginVersion = 0.0.1
pluginSinceBuild = 193
pluginUntilBuild = 201.*
pluginSinceBuild = 202
pluginUntilBuild = 202.*

platformType = IC
platformVersion = 2019.3
platformVersion = 2020.2
platformDownloadSources = true
23 changes: 23 additions & 0 deletions out/production/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<idea-plugin>
<id>ai.serenade.intellij</id>
<name>Serenade</name>
<vendor>Serenade</vendor>

<!-- Product and plugin compatibility requirements -->
<!-- https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html -->
<depends>com.intellij.modules.platform</depends>
<depends>com.intellij.modules.java</depends>

<extensions defaultExtensionNs="com.intellij">
<applicationService serviceImplementation="ai.serenade.intellij.services.MyApplicationService"/>
<projectService serviceImplementation="ai.serenade.intellij.services.MyProjectService"/>

<toolWindow id="My Sample Tool Window" anchor="right" factoryClass="ai.serenade.intellij.MainToolWindow"/>
</extensions>

<projectListeners>
<listener class="ai.serenade.intellij.listeners.MyProjectManagerListener"
topic="com.intellij.openapi.wm.ex.ToolWindowManagerListener"/>
</projectListeners>

</idea-plugin>
21 changes: 21 additions & 0 deletions src/main/kotlin/ai/serenade/intellij/MainToolWindow.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ai.serenade.intellij

import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowFactory
import com.intellij.ui.content.Content
import com.intellij.ui.content.ContentFactory
import com.intellij.ui.layout.panel

class MainToolWindow : ToolWindowFactory {
override fun createToolWindowContent(p0: Project, p1: ToolWindow) {
val contentFactory: ContentFactory = ContentFactory.SERVICE.getInstance()
val content: Content = contentFactory.createContent(panel {
noteRow("Welcome to Serenade!")
noteRow("With Serenade, you can write code faster&mdash;by speaking in plain English, rather than typing. Use Serenade as your coding assistant, or abandon your keyboard entirely.")
noteRow("To get started, download the Serenade app and run it alongside IntelliJ.")
noteRow("<a class=\"serenade-download\" href=\"https://serenade.ai/\">Download</a>")
}, "", false)
p1.contentManager.addContent(content)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,90 @@
package ai.serenade.intellij.listeners

import ai.serenade.intellij.services.MyProjectService
import com.google.gson.Gson
import com.intellij.notification.NotificationDisplayType
import com.intellij.notification.NotificationGroup
import com.intellij.notification.NotificationType
import com.intellij.notification.Notifications
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManagerListener
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ex.ToolWindowManagerListener
import io.ktor.client.HttpClient
import io.ktor.client.features.websocket.WebSockets
import io.ktor.client.features.websocket.ws
import io.ktor.http.HttpMethod
import io.ktor.http.cio.websocket.Frame
import io.ktor.http.cio.websocket.readText
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.launch

internal class MyProjectManagerListener : ProjectManagerListener {
data class Result(
val source: String,
val cursor: Int,
val filename: String,
val files: List<String>,
var roots: List<String>,
var tabs: List<String>
)

override fun projectOpened(project: Project) {
project.getService(MyProjectService::class.java)
data class Data(
val app: String,
val id: String
)

data class Message(
val message: String,
val data: Any
)

class MyProjectManagerListener(private val project: Project) : ToolWindowManagerListener {

override fun toolWindowShown(id: String, toolWindow: ToolWindow) {
val notificationGroup = NotificationGroup("Serenade", NotificationDisplayType.BALLOON, true)
val gson = Gson();
val editor = FileEditorManager.getInstance(project).selectedTextEditor
val document = editor?.document
val source = document?.text ?: ""

GlobalScope.launch {
val client = HttpClient {
install(WebSockets)
}
client.ws(
method = HttpMethod.Get,
host = "localhost",
port = 17373, path = "/"
) {
// Send text frame.
send(Frame.Text(gson.toJson(
Message("heartbeat", Data(
"/users/cheng/.gradle/caches/modules-2/files-2.1/com.jetbrains/jbre/jbr-11_0_7-osx-x64-b944.20/jbr/contents/home/bin/java",
java.util.UUID.randomUUID().toString()
))
)))

// Receive frames
incoming.consumeEach { frame ->
if (frame is Frame.Text) {
val notification = notificationGroup.createNotification(
frame.readText(), NotificationType.INFORMATION
)
Notifications.Bus.notify(notification, project)

send(Frame.Text(gson.toJson(
Message("editorState", Result(
source,
0,
"",
emptyList(),
emptyList(),
emptyList()
))
)))
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package ai.serenade.intellij.services

import ai.serenade.intellij.MyBundle

class MyApplicationService {

init {
println(MyBundle.message("applicationService"))
}
}
5 changes: 4 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceImplementation="ai.serenade.intellij.services.MyApplicationService"/>
<projectService serviceImplementation="ai.serenade.intellij.services.MyProjectService"/>

<toolWindow id="My Sample Tool Window" anchor="right" factoryClass="ai.serenade.intellij.MainToolWindow"/>
</extensions>

<projectListeners>
<listener class="ai.serenade.intellij.listeners.MyProjectManagerListener"
topic="com.intellij.openapi.project.ProjectManagerListener"/>
topic="com.intellij.openapi.wm.ex.ToolWindowManagerListener"/>
</projectListeners>

</idea-plugin>

0 comments on commit 6343d03

Please sign in to comment.