Skip to content

Commit

Permalink
fix(completions): include filterText property by default (#693)
Browse files Browse the repository at this point in the history
  • Loading branch information
rchl committed Feb 20, 2023
1 parent f645b06 commit c07426a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 8 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,17 @@ typescript-language-server --stdio

The language server accepts various settings through the `initializationOptions` object passed through the `initialize` request. Refer to your LSP client's documentation on how to set these. Here is the list of supported options:

| Setting | Type | Description |
|:------------------|:---------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| hostInfo | string | Information about the host, for example `"Emacs 24.4"` or `"Sublime Text v3075"`. **Default**: `undefined` |
| Setting | Type | Description |
|:------------------|:---------|:--------------------------------------------------------------------------------------|
| hostInfo | string | Information about the host, for example `"Emacs 24.4"` or `"Sublime Text v3075"`. **Default**: `undefined` |
| completionDisableFilterText | boolean | Don't set `filterText` property on completion items. **Default**: `false` |
| disableAutomaticTypingAcquisition | boolean | Disables tsserver from automatically fetching missing type definitions (`@types` packages) for external modules. |
| maxTsServerMemory | number | The maximum size of the V8's old memory section in megabytes (for example `4096` means 4GB). The default value is dynamically configured by Node so can differ per system. Increase for very big projects that exceed allowed memory usage. **Default**: `undefined` |
| npmLocation | string | Specifies the path to the NPM executable used for Automatic Type Acquisition. |
| locale | string | The locale to use to show error messages. |
| plugins | object[] | An array of `{ name: string, location: string }` objects for registering a Typescript plugins. **Default**: [] |
| preferences | object | Preferences passed to the Typescript (`tsserver`) process. See below for more info. |
| tsserver | object | Options related to the `tsserver` process. See below for more info. |
| plugins | object[] | An array of `{ name: string, location: string }` objects for registering a Typescript plugins. **Default**: [] |
| preferences | object | Preferences passed to the Typescript (`tsserver`) process. See below for more |
| tsserver | object | Options related to the `tsserver` process. See below for more |

The `tsserver` setting specifies additional options related to the internal `tsserver` process, like tracing and logging.

Expand Down
46 changes: 44 additions & 2 deletions src/completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,18 @@ export function asCompletionItem(
item.detail = Previewer.plainWithLinks(sourceDisplay, filePathConverter);
}

const { optionalReplacementRange, isMemberCompletion, dotAccessorContext } = completionContext;
const { line, optionalReplacementRange, isMemberCompletion, dotAccessorContext } = completionContext;
let range = getRangeFromReplacementSpan(replacementSpan, optionalReplacementRange, position, document, features);
let { insertText } = entry;
if (!features.completionDisableFilterText) {
item.filterText = getFilterText(entry, optionalReplacementRange, line, insertText);
}

if (isMemberCompletion && dotAccessorContext && !entry.isSnippet) {
const newInsertText = dotAccessorContext.text + (insertText || item.label);
if (!features.completionDisableFilterText) {
item.filterText = newInsertText;
}
if (!range) {
if (features.completionInsertReplaceSupport && optionalReplacementRange) {
range = {
Expand All @@ -102,7 +109,7 @@ export function asCompletionItem(
} else {
range = { replace: dotAccessorContext.range };
}
insertText = dotAccessorContext.text + (insertText || item.label);
insertText = newInsertText;
}
}

Expand Down Expand Up @@ -169,6 +176,41 @@ function getRangeFromReplacementSpan(
}
}

function getFilterText(entry: ts.server.protocol.CompletionEntry, wordRange: lsp.Range | undefined, line: string, insertText: string | undefined): string | undefined {
// Handle private field completions
if (entry.name.startsWith('#')) {
const wordStart = wordRange ? line.charAt(wordRange.start.character) : undefined;
if (insertText) {
if (insertText.startsWith('this.#')) {
return wordStart === '#' ? insertText : insertText.replace(/&this\.#/, '');
} else {
return wordStart;
}
} else {
return wordStart === '#' ? undefined : entry.name.replace(/^#/, '');
}
}

// For `this.` completions, generally don't set the filter text since we don't want them to be overly prioritized. #74164
if (insertText?.startsWith('this.')) {
return undefined;
}

// Handle the case:
// ```
// const xyz = { 'ab c': 1 };
// xyz.ab|
// ```
// In which case we want to insert a bracket accessor but should use `.abc` as the filter text instead of
// the bracketed insert text.
if (insertText?.startsWith('[')) {
return insertText.replace(/^\[['"](.+)[['"]\]$/, '.$1');
}

// In all other cases, fallback to using the insertText
return insertText;
}

function ensureRangeIsOnSingleLine(range: lsp.Range, document: LspDocument): lsp.Range {
if (range.start.line !== range.end.line) {
return lsp.Range.create(range.start, document.getLineEnd(range.start.line));
Expand Down
1 change: 1 addition & 0 deletions src/lsp-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export class LspServer {
this.configurationManager.mergeTsPreferences(userInitializationOptions.preferences || {});

// Setup supported features.
this.features.completionDisableFilterText = userInitializationOptions.completionDisableFilterText ?? false;
const { textDocument } = clientCapabilities;
if (textDocument) {
const { codeAction, completion, definition, publishDiagnostics } = textDocument;
Expand Down
2 changes: 2 additions & 0 deletions src/ts-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export interface SupportedFeatures {
completionInsertReplaceSupport?: boolean;
completionLabelDetails?: boolean;
completionSnippets?: boolean;
completionDisableFilterText?: boolean;
definitionLinkSupport?: boolean;
diagnosticsTagSupport?: boolean;
}
Expand All @@ -335,6 +336,7 @@ export interface TypeScriptPlugin {
}

export interface TypeScriptInitializationOptions {
completionDisableFilterText?: boolean;
disableAutomaticTypingAcquisition?: boolean;
hostInfo?: string;
locale?: string;
Expand Down

0 comments on commit c07426a

Please sign in to comment.