This repository was archived by the owner on Feb 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Use lsp-client #36
Open
chrismwendt
wants to merge
8
commits into
master
Choose a base branch
from
lsp-client
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Use lsp-client #36
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
94d914d
wip on lsp-client (must yarn link @sourcegraph/lsp-client with change…
chrismwendt dfe2969
.
chrismwendt 54b0358
.
chrismwendt 09e9351
.
chrismwendt 1d15a8e
new lsp-client
chrismwendt 5134002
newer lsp-client
chrismwendt 16a3803
only use file:// URIs for older go-langserver versions
chrismwendt 0a8f4a1
Restructure
chrismwendt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import * as lspClient from '@sourcegraph/lsp-client' | ||
import '@babel/polyfill' | ||
|
||
import { activateBasicCodeIntel, registerFeedbackButton } from '@sourcegraph/basic-code-intel' | ||
|
@@ -26,6 +27,8 @@ import { | |
import { ConsoleLogger, createWebSocketConnection } from '@sourcegraph/vscode-ws-jsonrpc' | ||
import gql from 'tagged-template-noop' | ||
import { Settings } from './settings' | ||
import { TextDocument } from 'sourcegraph' | ||
import { NoopLogger } from '@sourcegraph/lsp-client/dist/logging' | ||
|
||
// If we can rid ourselves of file:// URIs, this type won't be necessary and we | ||
// can use lspext.Xreference directly. | ||
|
@@ -481,7 +484,12 @@ function xrefs({ | |
const definitions = (await sendRequest({ | ||
rootURI: rootURIFromDoc(doc), | ||
requestType: new lsp.RequestType<any, any, any, void>('textDocument/xdefinition') as any, | ||
request: positionParams(doc, pos), | ||
request: { | ||
textDocument: { | ||
uri: doc.uri, | ||
}, | ||
position: pos, | ||
}, | ||
useCache: true, | ||
})) as lspext.Xdefinition[] | null | ||
if (!definitions) { | ||
|
@@ -551,22 +559,49 @@ function xrefs({ | |
) | ||
} | ||
|
||
function positionParams(doc: sourcegraph.TextDocument, pos: sourcegraph.Position): lsp.TextDocumentPositionParams { | ||
return { | ||
textDocument: { | ||
uri: `file:///${new URL(doc.uri).hash.slice(1)}`, | ||
}, | ||
position: { | ||
line: pos.line, | ||
character: pos.character, | ||
}, | ||
} | ||
/** | ||
* Automatically registers/deregisters a provider based on the given predicate of the settings. | ||
*/ | ||
function registerWhile({ | ||
register, | ||
settings, | ||
settingsPredicate, | ||
}: { | ||
register: () => sourcegraph.Unsubscribable | ||
settings: Observable<Settings> | ||
settingsPredicate: (settings: Settings) => boolean | ||
}): sourcegraph.Unsubscribable { | ||
let registration: sourcegraph.Unsubscribable | undefined | ||
return from(settings) | ||
.pipe( | ||
map(settingsPredicate), | ||
distinctUntilChanged(), | ||
map(enabled => { | ||
if (enabled) { | ||
registration = register() | ||
} else { | ||
if (registration) { | ||
registration.unsubscribe() | ||
registration = undefined | ||
} | ||
} | ||
}), | ||
finalize(() => { | ||
if (registration) { | ||
registration.unsubscribe() | ||
registration = undefined | ||
} | ||
}) | ||
) | ||
.subscribe() | ||
} | ||
|
||
/** | ||
* Uses WebSockets to communicate with a language server. | ||
*/ | ||
export async function activateUsingWebSockets(ctx: sourcegraph.ExtensionContext): Promise<void> { | ||
export async function activatePreciseDeprecated(ctx: sourcegraph.ExtensionContext): Promise<void> { | ||
ctx.subscriptions.add(registerFeedbackButton({ languageID: 'go', sourcegraph, isPrecise: true })) | ||
|
||
const accessToken = await getOrTryToCreateAccessToken() | ||
const settings: BehaviorSubject<Settings> = new BehaviorSubject<Settings>({}) | ||
ctx.subscriptions.add( | ||
|
@@ -611,7 +646,12 @@ export async function activateUsingWebSockets(ctx: sourcegraph.ExtensionContext) | |
sendRequest({ | ||
rootURI: rootURIFromDoc(doc), | ||
requestType: ty, | ||
request: positionParams(doc, pos), | ||
request: { | ||
textDocument: { | ||
uri: `file:///${new URL(doc.uri).hash.slice(1)}`, | ||
}, | ||
position: pos, | ||
}, | ||
useCache, | ||
}) | ||
|
||
|
@@ -652,41 +692,6 @@ export async function activateUsingWebSockets(ctx: sourcegraph.ExtensionContext) | |
}) | ||
) | ||
|
||
/** | ||
* Automatically registers/deregisters a provider based on the given predicate of the settings. | ||
*/ | ||
function registerWhile({ | ||
register, | ||
settingsPredicate, | ||
}: { | ||
register: () => sourcegraph.Unsubscribable | ||
settingsPredicate: (settings: Settings) => boolean | ||
}): sourcegraph.Unsubscribable { | ||
let registration: sourcegraph.Unsubscribable | undefined | ||
return from(settings) | ||
.pipe( | ||
map(settingsPredicate), | ||
distinctUntilChanged(), | ||
map(enabled => { | ||
if (enabled) { | ||
registration = register() | ||
} else { | ||
if (registration) { | ||
registration.unsubscribe() | ||
registration = undefined | ||
} | ||
} | ||
}), | ||
finalize(() => { | ||
if (registration) { | ||
registration.unsubscribe() | ||
registration = undefined | ||
} | ||
}) | ||
) | ||
.subscribe() | ||
} | ||
|
||
ctx.subscriptions.add( | ||
registerWhile({ | ||
register: () => | ||
|
@@ -701,6 +706,7 @@ export async function activateUsingWebSockets(ctx: sourcegraph.ExtensionContext) | |
map(response => convert.xreferences({ references: response })) | ||
), | ||
}), | ||
settings, | ||
settingsPredicate: settings => Boolean(settings['go.showExternalReferences']), | ||
}) | ||
) | ||
|
@@ -727,6 +733,94 @@ export async function activateUsingWebSockets(ctx: sourcegraph.ExtensionContext) | |
ctx.subscriptions.add(panelView) | ||
} | ||
|
||
function activateImprecise(ctx: sourcegraph.ExtensionContext): void { | ||
ctx.subscriptions.add( | ||
registerFeedbackButton({ | ||
languageID: 'go', | ||
sourcegraph, | ||
isPrecise: false, | ||
}) | ||
) | ||
|
||
activateBasicCodeIntel({ | ||
sourcegraph, | ||
languageID: 'go', | ||
fileExts: ['go'], | ||
filterDefinitions: ({ repo, filePath, pos, fileContent, results }) => { | ||
const currentFileImportedPaths = fileContent | ||
.split('\n') | ||
.map(line => { | ||
// Matches the import at index 3 | ||
const match = /^(import |\t)(\w+ |\. )?"(.*)"$/.exec(line) | ||
return match ? match[3] : undefined | ||
}) | ||
.filter((x): x is string => Boolean(x)) | ||
|
||
const currentFileImportPath = repo + '/' + path.dirname(filePath) | ||
|
||
const filteredResults = results.filter(result => { | ||
const resultImportPath = result.repo + '/' + path.dirname(result.file) | ||
return ( | ||
currentFileImportedPaths.some(i => resultImportPath.includes(i)) || | ||
resultImportPath === currentFileImportPath | ||
) | ||
}) | ||
|
||
return filteredResults.length === 0 ? results : filteredResults | ||
}, | ||
commentStyle: { | ||
lineRegex: /\/\/\s?/, | ||
}, | ||
})(ctx) | ||
} | ||
|
||
async function activatePreciseUsingLspClient(ctx: sourcegraph.ExtensionContext): Promise<void> { | ||
ctx.subscriptions.add(registerFeedbackButton({ languageID: 'go', sourcegraph, isPrecise: true })) | ||
|
||
const token = await getOrTryToCreateAccessToken() | ||
|
||
const serverURL = sourcegraph.configuration.get<Settings>().value['go.serverUrl'] | ||
const client = await lspClient.register({ | ||
sourcegraph, | ||
transport: lspClient.webSocketTransport({ | ||
serverUrl: serverURL!, | ||
logger: new NoopLogger(), | ||
}), | ||
documentSelector: [{ language: 'go' }], | ||
initializationOptions: { | ||
zipURLTemplate: zipURLTemplate(token), | ||
}, | ||
}) | ||
ctx.subscriptions.add(client) | ||
|
||
const settings: BehaviorSubject<Settings> = new BehaviorSubject<Settings>({}) | ||
ctx.subscriptions.add( | ||
sourcegraph.configuration.subscribe(() => { | ||
settings.next(sourcegraph.configuration.get<Settings>().value) | ||
}) | ||
) | ||
|
||
ctx.subscriptions.add( | ||
registerWhile({ | ||
register: () => | ||
sourcegraph.languages.registerReferenceProvider([{ pattern: '*.go' }], { | ||
provideReferences: (doc: sourcegraph.TextDocument, pos: sourcegraph.Position) => | ||
xrefs({ | ||
doc, | ||
pos, | ||
sendRequest: ({ rootURI, requestType, request, useCache }) => | ||
client.withConnection(rootURI, conn => conn.sendRequest(requestType, request)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the part that gets into an infinite loop without sourcegraph/lsp-client#42 |
||
}).pipe( | ||
scan((acc: XRef[], curr: XRef) => [...acc, curr], [] as XRef[]), | ||
map(response => convert.xreferences({ references: response })) | ||
), | ||
}), | ||
settings, | ||
settingsPredicate: settings => Boolean(settings['go.showExternalReferences']), | ||
}) | ||
) | ||
} | ||
|
||
function pathname(url: string): string { | ||
let pathname = url | ||
pathname = pathname.slice('git://'.length) | ||
|
@@ -738,52 +832,15 @@ function pathname(url: string): string { | |
const DUMMY_CTX = { subscriptions: { add: (_unsubscribable: any) => void 0 } } | ||
|
||
export function activate(ctx: sourcegraph.ExtensionContext = DUMMY_CTX): void { | ||
async function afterActivate(): Promise<void> { | ||
const address = sourcegraph.configuration.get<Settings>().get('go.serverUrl') | ||
if (address) { | ||
ctx.subscriptions.add(registerFeedbackButton({ languageID: 'go', sourcegraph, isPrecise: true })) | ||
|
||
await activateUsingWebSockets(ctx) | ||
setTimeout(async function afterActivate(): Promise<void> { | ||
if (sourcegraph.configuration.get<Settings>().get('go.serverUrl')) { | ||
if (sourcegraph.configuration.get().get('lspclient')) { | ||
await activatePreciseUsingLspClient(ctx) | ||
} else { | ||
await activatePreciseDeprecated(ctx) | ||
} | ||
} else { | ||
ctx.subscriptions.add( | ||
registerFeedbackButton({ | ||
languageID: 'go', | ||
sourcegraph, | ||
isPrecise: false, | ||
}) | ||
) | ||
|
||
activateBasicCodeIntel({ | ||
sourcegraph, | ||
languageID: 'go', | ||
fileExts: ['go'], | ||
filterDefinitions: ({ repo, filePath, pos, fileContent, results }) => { | ||
const currentFileImportedPaths = fileContent | ||
.split('\n') | ||
.map(line => { | ||
// Matches the import at index 3 | ||
const match = /^(import |\t)(\w+ |\. )?"(.*)"$/.exec(line) | ||
return match ? match[3] : undefined | ||
}) | ||
.filter((x): x is string => Boolean(x)) | ||
|
||
const currentFileImportPath = repo + '/' + path.dirname(filePath) | ||
|
||
const filteredResults = results.filter(result => { | ||
const resultImportPath = result.repo + '/' + path.dirname(result.file) | ||
return ( | ||
currentFileImportedPaths.some(i => resultImportPath.includes(i)) || | ||
resultImportPath === currentFileImportPath | ||
) | ||
}) | ||
|
||
return filteredResults.length === 0 ? results : filteredResults | ||
}, | ||
commentStyle: { | ||
lineRegex: /\/\/\s?/, | ||
}, | ||
})(ctx) | ||
activateImprecise(ctx) | ||
} | ||
} | ||
setTimeout(afterActivate, 100) | ||
}, 100) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function
activatePreciseUsingLspClient
is really the only new piece in this PR. The other changes were due to restructuring the code.