Skip to content
This repository was archived by the owner on Jul 25, 2022. It is now read-only.

Commit e85b1b8

Browse files
authored
Get active connection on demand for window focus callbacks (#82)
1 parent 2cc0296 commit e85b1b8

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

src/main/scala/servers/Metals.scala

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import scala.scalajs.js, js.annotation._
44
import org.scalajs.dom, dom.raw.Element
55
import laughedelic.atom.Atom
66
import laughedelic.atom.config._
7-
import laughedelic.atom.languageclient.ActiveServer
7+
import laughedelic.atom.languageclient.{ActiveServer, LanguageClientConnection}
88
import scala.concurrent._, ExecutionContext.Implicits.global
99

1010
// For matching glob patterns
@@ -69,25 +69,22 @@ object Metals extends ScalaLanguageServer { server =>
6969

7070
override def postInitialization(client: ScalaLanguageClient, activeServer: ActiveServer): Unit = {
7171
val projectPath = activeServer.projectPath
72-
val connection = activeServer.connection.asInstanceOf[js.Dynamic]
7372

74-
connection
73+
// HtmlView needs to be registered so that Atom knows how to render it
74+
Atom.asInstanceOf[js.Dynamic]
75+
.views
76+
.addViewProvider( { _.getViewClass }: js.Function1[HtmlView, Element] )
77+
78+
// Here we can use activeServer.connection to attach callbacks for custom LSP messages
79+
activeServer.connection.asInstanceOf[js.Dynamic]
7580
.onCustom("metals/status", { params: js.Dynamic =>
7681
Atom.workspace.getActiveTextEditor().foreach { editor =>
7782
if (client.isFileInProject(editor, projectPath)) {
7883
client.statusBarTile.innerHTML = params.text.toString
7984
}
8085
}
8186
})
82-
83-
// HtmlView needs to be registered so that Atom knows how to render it
84-
Atom.asInstanceOf[js.Dynamic]
85-
.views
86-
.addViewProvider(
87-
{ _.getViewClass }: js.Function1[HtmlView, Element]
88-
)
89-
90-
connection
87+
activeServer.connection.asInstanceOf[js.Dynamic]
9188
.onCustom("metals/executeClientCommand", { params: js.Dynamic =>
9289
params.command.toString match {
9390
case "metals-logs-toggle" =>
@@ -109,19 +106,36 @@ object Metals extends ScalaLanguageServer { server =>
109106
}
110107
})
111108

109+
// activeServer.connection will be disposed, so we need to ask for the active connection on demand
110+
def withActiveConnection(action: LanguageClientConnection => Unit): Unit = {
111+
Atom.workspace.getActiveTextEditor()
112+
.filter(client.shouldStartForEditor)
113+
.foreach { editor =>
114+
client
115+
.getConnectionForEditor(editor).toFuture
116+
.foreach { connectionOrUndef =>
117+
connectionOrUndef.foreach(action)
118+
}
119+
}
120+
}
121+
112122
// Send windowStateDidChange notification to Metals every time window is in/out of focus
113123
Atom.asInstanceOf[js.Dynamic].getCurrentWindow()
114124
.on("focus", { _: js.Any =>
115-
connection.sendCustomNotification(
116-
"metals/windowStateDidChange",
117-
js.Dynamic.literal("focused" -> true)
118-
)
125+
withActiveConnection { connection =>
126+
connection.asInstanceOf[js.Dynamic].sendCustomNotification(
127+
"metals/windowStateDidChange",
128+
js.Dynamic.literal("focused" -> true)
129+
)
130+
}
119131
})
120132
.on("blur", { _: js.Any =>
121-
connection.sendCustomNotification(
122-
"metals/windowStateDidChange",
123-
js.Dynamic.literal("focused" -> false)
124-
)
133+
withActiveConnection { connection =>
134+
connection.asInstanceOf[js.Dynamic].sendCustomNotification(
135+
"metals/windowStateDidChange",
136+
js.Dynamic.literal("focused" -> false)
137+
)
138+
}
125139
})
126140

127141
Atom.workspace.onDidChangeActiveTextEditor { editorOrUndef =>

0 commit comments

Comments
 (0)