@@ -4,7 +4,7 @@ import scala.scalajs.js, js.annotation._
44import org .scalajs .dom , dom .raw .Element
55import laughedelic .atom .Atom
66import laughedelic .atom .config ._
7- import laughedelic .atom .languageclient .ActiveServer
7+ import laughedelic .atom .languageclient .{ ActiveServer , LanguageClientConnection }
88import 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