diff --git a/src/features/definition.ts b/src/features/definition.ts index 081d160..26f277b 100644 --- a/src/features/definition.ts +++ b/src/features/definition.ts @@ -15,7 +15,7 @@ export const definitionFeature: Feature serverToClientURI(uri, scopeRootUri)) return convertLocations(sourcegraph, result as Location | Location[] | null) }, } diff --git a/src/features/feature.ts b/src/features/feature.ts index a2ade9e..881482f 100644 --- a/src/features/feature.ts +++ b/src/features/feature.ts @@ -14,7 +14,7 @@ export interface Feature, C extends ke sourcegraph: typeof import('sourcegraph') scopeRootUri: URL | null clientToServerURI: (uri: URL) => URL - serverToClientURI: (uri: URL) => URL + serverToClientURI: (uri: URL, scopeRootUri: URL | null) => URL registerOptions: RegistrationOptions }): Unsubscribable } diff --git a/src/features/hover.ts b/src/features/hover.ts index 5aa3cde..9f4335b 100644 --- a/src/features/hover.ts +++ b/src/features/hover.ts @@ -15,7 +15,7 @@ export const hoverFeature: Feature = HoverRequest.type, convertProviderParams({ textDocument, position }, { clientToServerURI }) ) - rewriteUris(result, serverToClientURI) + rewriteUris(result, uri => serverToClientURI(uri, scopeRootUri)) return convertHover(sourcegraph, result) }, } diff --git a/src/features/references.ts b/src/features/references.ts index 9a039c8..2722494 100644 --- a/src/features/references.ts +++ b/src/features/references.ts @@ -15,7 +15,7 @@ export const referencesFeature: Feature serverToClientURI(uri, scopeRootUri)) return convertLocations(sourcegraph, result) }, } diff --git a/src/index.ts b/src/index.ts index 7c7b941..0656abc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import { differenceBy, identity } from 'lodash' import * as path from 'path' import { from, noop, Subscription, Unsubscribable } from 'rxjs' -import { map, scan, startWith } from 'rxjs/operators' +import { map, scan, startWith, buffer, debounceTime } from 'rxjs/operators' import { DocumentSelector, ProgressReporter, WorkspaceRoot } from 'sourcegraph' import * as uuid from 'uuid' import { @@ -71,11 +71,12 @@ export interface RegisterOptions { sourcegraph: SourcegraphAPI supportsWorkspaceFolders?: boolean clientToServerURI?: (uri: URL) => URL - serverToClientURI?: (uri: URL) => URL + serverToClientURI?: (uri: URL, scopeRootUri: URL | null) => URL afterInitialize?: (initializeResult: InitializeResult) => Promise | void logger?: Logger transport: () => Promise | LSPConnection documentSelector: DocumentSelector + additionalInitializationOptions?: (url: URL) => any } export async function register({ sourcegraph, @@ -87,6 +88,7 @@ export async function register({ afterInitialize = noop, transport: createConnection, documentSelector, + additionalInitializationOptions, }: RegisterOptions): Promise { const subscriptions = new Subscription() // tslint:disable-next-line:no-object-literal-type-assertion @@ -153,7 +155,10 @@ export async function register({ } } - async function connect(clientRootUri: URL | null, initParams: InitializeParams): Promise { + async function connect( + clientRootUri: URL | null, + initParams: InitializeParams + ): Promise { const subscriptions = new Subscription() const decorationType = sourcegraph.app.createDecorationType() const connection = await createConnection() @@ -188,7 +193,7 @@ export async function register({ subscriptions.add( connection.observeNotification(PublishDiagnosticsNotification.type).subscribe(params => { const uri = new URL(params.uri) - const sourcegraphTextDocumentUri = serverToClientURI(uri) + const sourcegraphTextDocumentUri = serverToClientURI(uri, clientRootUri) diagnosticsByUri.set(sourcegraphTextDocumentUri.href, params.diagnostics) for (const appWindow of sourcegraph.app.windows) { for (const viewComponent of appWindow.visibleViewComponents) { @@ -265,7 +270,12 @@ export async function register({ clientRootUri: URL | null, initParams: InitializeParams ): Promise { - const initializeResult = await connection.sendRequest(InitializeRequest.type, initParams) + // TODO passing a function around in initializationOptions is hacky, + // consider moving it to a separate parameter + if (initParams.initializationOptions && clientRootUri) { + initParams.initializationOptions = initParams.initializationOptions(clientRootUri) + } + const initializeResult = await connection.sendRequest(InitializeRequest.type, { ...initParams, rootPath: '/' }) // Tell language server about all currently open text documents under this root syncTextDocuments(connection) @@ -292,6 +302,7 @@ export async function register({ rootUri: null, capabilities: clientCapabilities, workspaceFolders: sourcegraph.workspace.roots.map(toLSPWorkspaceFolder({ clientToServerURI })), + initializationOptions: additionalInitializationOptions, } ) subscriptions.add(connection) @@ -361,6 +372,7 @@ export async function register({ rootUri: serverRootUri.href, capabilities: clientCapabilities, workspaceFolders: null, + initializationOptions: additionalInitializationOptions, } ) subscriptions.add(connection) @@ -383,6 +395,7 @@ export async function register({ rootUri: serverRootUri.href, capabilities: clientCapabilities, workspaceFolders: null, + initializationOptions: additionalInitializationOptions, } ) subscriptions.add(connection) @@ -399,6 +412,10 @@ export async function register({ subscriptions.add( from(sourcegraph.workspace.rootChanges) .pipe( + // TODO try to fix sourcegraph/sourcegraph so that it + // doesn't emit empty workspace roots between page + // navigations + buffer(from(sourcegraph.workspace.rootChanges).pipe(debounceTime(1000))), startWith(null), map(() => [...sourcegraph.workspace.roots]), scan((before, after) => {