Skip to content
This repository has been archived by the owner on Nov 5, 2018. It is now read-only.

Commit

Permalink
[server] moved selection sync code from yang-lsp to sprotty
Browse files Browse the repository at this point in the history
  • Loading branch information
JanKoehnlein committed Aug 22, 2017
1 parent 6ae43fa commit f030bc6
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class DiagramLanguageServerExtension implements DiagramServerEndpoint, ILanguage
updateDiagrams(deltas.map[uri].toSet)
]
}

def ILanguageServerAccess getLanguageServerAccess() {
languageServerAccess
}

protected def DiagramEndpoint getClient() {
if (_client === null) {
Expand Down Expand Up @@ -95,7 +99,7 @@ class DiagramLanguageServerExtension implements DiagramServerEndpoint, ILanguage
server.languageServerExtension = this
}

protected def List<? extends IDiagramServer> findDiagramServersByUri(String uri) {
def List<? extends IDiagramServer> findDiagramServersByUri(String uri) {
synchronized (diagramServers) {
diagramServers.values.filter(LanguageAwareDiagramServer).filter[sourceUri == uri].toList
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.typefox.sprotty.server.xtext.ide

import io.typefox.sprotty.server.xtext.DiagramEndpoint
import org.eclipse.lsp4j.Location
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
import org.eclipse.lsp4j.jsonrpc.services.JsonSegment

@JsonSegment('diagram')
interface IdeDiagramClient extends DiagramEndpoint {

@JsonNotification
def void openInTextEditor(Location location)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.typefox.sprotty.server.xtext.ide

import io.typefox.sprotty.server.xtext.DefaultDiagramModule
import org.eclipse.xtext.ide.server.occurrences.IDocumentHighlightService
import io.typefox.sprotty.server.xtext.DiagramLanguageServerExtension

class IdeDiagramModule extends DefaultDiagramModule {

def Class<? extends DiagramLanguageServerExtension> bindDiagramLanguageServerExtension() {
IdeLanguageServerExtension
}

override bindIDiagramServerProvider() {
IdeLanguageServerExtension
}

def Class<? extends IDocumentHighlightService> bindIDocumentHighlightService() {
IdeHighlightService
}

override bindIDiagramSelectionListener() {
IdeDiagramSelectionListener
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.typefox.sprotty.server.xtext.ide

import com.google.inject.Inject
import io.typefox.sprotty.api.IDiagramSelectionListener
import io.typefox.sprotty.api.IDiagramServer
import io.typefox.sprotty.api.SModelIndex
import io.typefox.sprotty.api.SelectAction
import io.typefox.sprotty.server.xtext.DiagramLanguageServerExtension
import io.typefox.sprotty.server.xtext.LanguageAwareDiagramServer
import org.eclipse.emf.common.util.URI
import org.eclipse.lsp4j.Location
import org.eclipse.lsp4j.Range
import org.eclipse.xtext.ide.server.UriExtensions

class IdeDiagramSelectionListener implements IDiagramSelectionListener {

@Inject extension DiagramLanguageServerExtension

@Inject extension UriExtensions

override selectionChanged(SelectAction action, IDiagramServer server) {
if(server instanceof LanguageAwareDiagramServer) {
val languageServerExtension = server.languageServerExtension
if(languageServerExtension instanceof IdeLanguageServerExtension) {
if(!action.deselectAll && action.selectedElementsIDs !== null && action.selectedElementsIDs.size === 1) {
val id = action.selectedElementsIDs.head
val selectedElement = new SModelIndex(server.model).get(id)
if (selectedElement instanceof io.typefox.sprotty.server.xtext.tracing.Traceable) {
val traceRegion = selectedElement.significantRegion
if(traceRegion !== null) {
val uri = server.sourceUri
if(uri !== null) {
uri.findDiagramServersByUri.forEach[
languageServerExtension.languageServerAccess.doRead(
URI.createURI(uri).toPath, [ context |
val start = context.document.getPosition(traceRegion.offset)
val end = context.document.getPosition(traceRegion.offset + traceRegion.length)
languageServerExtension.client.openInTextEditor(new Location(uri, new Range(start, end)))
return null
])
]
}
}
}
}
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.typefox.sprotty.server.xtext.ide

import com.google.inject.Inject
import io.typefox.sprotty.api.FitToScreenAction
import io.typefox.sprotty.api.SModelElement
import io.typefox.sprotty.api.SelectAction
import io.typefox.sprotty.server.xtext.DiagramLanguageServerExtension
import java.util.function.Consumer
import org.eclipse.xtext.ide.server.occurrences.DefaultDocumentHighlightService
import org.eclipse.xtext.resource.EObjectAtOffsetHelper
import org.eclipse.xtext.resource.XtextResource

class IdeHighlightService extends DefaultDocumentHighlightService {

@Inject extension DiagramLanguageServerExtension

@Inject extension EObjectAtOffsetHelper

override getDocumentHighlights(XtextResource resource, int offset) {
val result = super.getDocumentHighlights(resource, offset)
val element = resolveElementAt(resource, offset)
if (element !== null) {
findDiagramServersByUri(resource.getURI.toString).forEach [ server |
val traceables = <io.typefox.sprotty.server.xtext.tracing.Traceable>newArrayList()
server.model.findTraceablesAtOffset(offset, [
traceables += it
])
if(!traceables.empty) {
val smallest = traceables.minBy[ traceRegion.length ]
server.dispatch(new SelectAction [
selectedElementsIDs = #[(smallest as SModelElement).id]
deselectAll = true
])
server.dispatch(new FitToScreenAction [
maxZoom = 1.0
elementIds = #[(smallest as SModelElement).id]
])
}
]
}
return result
}

protected def void findTraceablesAtOffset(SModelElement root, int offset, Consumer<io.typefox.sprotty.server.xtext.tracing.Traceable> consumer) {
if (root instanceof io.typefox.sprotty.server.xtext.tracing.Traceable) {
val traceRegion = root.traceRegion
if(traceRegion !== null && traceRegion.offset <= offset && traceRegion.offset + traceRegion.length > offset)
consumer.accept(root)
}
root.children?.forEach[
findTraceablesAtOffset(offset, consumer)
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.typefox.sprotty.server.xtext.ide

import io.typefox.sprotty.server.xtext.DiagramLanguageServerExtension
import org.eclipse.lsp4j.jsonrpc.Endpoint
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints

class IdeLanguageServerExtension extends DiagramLanguageServerExtension {

IdeDiagramClient _client

override protected IdeDiagramClient getClient() {
if (_client === null) {
val client = languageServerAccess.languageClient
if (client instanceof Endpoint) {
_client = ServiceEndpoints.toServiceObject(client, IdeDiagramClient)
}
}
return _client
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.typefox.sprotty.server.xtext.tracing

import io.typefox.sprotty.server.xtext.tracing.TextRegion
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EStructuralFeature
import org.eclipse.emf.ecore.EcorePackage
import org.eclipse.xtext.nodemodel.INode
import org.eclipse.xtext.nodemodel.util.NodeModelUtils

class TraceRegionProvider {

def TextRegion getTraceRegion(EObject element) {
val node = NodeModelUtils.findActualNodeFor(element)
if (node !== null) {
val document = node.rootNode.text
val leafNodes = node.leafNodes.filter[!hidden]
if(!leafNodes.empty) {
var start = leafNodes.head.offset
while (start > 0 && document.charAt(start - 1) === 32)
start--
var end = leafNodes.last.endOffset
while(end < document.length && document.charAt(end) === 32)
end++
return new TextRegion(start, end - start)
}
}
return null
}

def TextRegion getSignificantRegion(EObject element) {
val feature = element.relevantFeature
if (feature !== null)
return NodeModelUtils.findNodesForFeature(element, feature).head.toTextRegion
else
return NodeModelUtils.findActualNodeFor(element).toTextRegion
}

protected def toTextRegion(INode node) {
val leafNodes = node.leafNodes.filter[!hidden]
if(!leafNodes.empty) {
var start = leafNodes.head.offset
var end = leafNodes.last.endOffset
return new TextRegion(start, end - start)
}
}

protected def EStructuralFeature getRelevantFeature(EObject element) {
element.eClass.getEAllAttributes.findFirst[name == 'name']
?: element.eClass.getEAllAttributes.findFirst[getEAttributeType === EcorePackage.Literals.ESTRING]
?: element.eClass.getEAllReferences.findFirst[isContainment && upperBound === 1]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.typefox.sprotty.server.xtext.tracing

import org.eclipse.xtend.lib.annotations.Data

interface Traceable {
def TextRegion getTraceRegion()
def void setTraceRegion(TextRegion traceRegion)
def TextRegion getSignificantRegion()
def void setSignificantRegion(TextRegion traceRegion)
}

@Data
class TextRegion {
int offset
int length
}

0 comments on commit f030bc6

Please sign in to comment.