Skip to content

Commit 687853e

Browse files
committed
1 parent 34fb5e9 commit 687853e

1 file changed

Lines changed: 30 additions & 10 deletions

File tree

src/vs/editor/contrib/suggest/suggestModel.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
2121
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
2222
import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance';
2323
import { EditorOption } from 'vs/editor/common/config/editorOptions';
24+
import { isLowSurrogate, isHighSurrogate } from 'vs/base/common/strings';
2425

2526
export interface ICancelEvent {
2627
readonly retrigger: boolean;
@@ -95,7 +96,7 @@ export class SuggestModel implements IDisposable {
9596

9697
private readonly _toDispose = new DisposableStore();
9798
private _quickSuggestDelay: number = 10;
98-
private _triggerCharacterListener?: IDisposable;
99+
private readonly _triggerCharacterListener = new DisposableStore();
99100
private readonly _triggerQuickSuggest = new TimeoutTimer();
100101
private _state: State = State.Idle;
101102

@@ -181,8 +182,7 @@ export class SuggestModel implements IDisposable {
181182
}
182183

183184
private _updateTriggerCharacters(): void {
184-
185-
dispose(this._triggerCharacterListener);
185+
this._triggerCharacterListener.clear();
186186

187187
if (this._editor.getOption(EditorOption.readOnly)
188188
|| !this._editor.hasModel()
@@ -191,29 +191,49 @@ export class SuggestModel implements IDisposable {
191191
return;
192192
}
193193

194-
const supportsByTriggerCharacter: { [ch: string]: Set<CompletionItemProvider> } = Object.create(null);
194+
const supportsByTriggerCharacter = new Map<string, Set<CompletionItemProvider>>();
195195
for (const support of CompletionProviderRegistry.all(this._editor.getModel())) {
196196
for (const ch of support.triggerCharacters || []) {
197-
let set = supportsByTriggerCharacter[ch];
197+
let set = supportsByTriggerCharacter.get(ch);
198198
if (!set) {
199-
set = supportsByTriggerCharacter[ch] = new Set();
199+
set = new Set();
200200
set.add(getSnippetSuggestSupport());
201+
supportsByTriggerCharacter.set(ch, set);
201202
}
202203
set.add(support);
203204
}
204205
}
205206

206-
this._triggerCharacterListener = this._editor.onDidType(text => {
207-
const lastChar = text.charAt(text.length - 1);
208-
const supports = supportsByTriggerCharacter[lastChar];
209207

208+
const checkTriggerCharacter = (text?: string) => {
209+
210+
if (!text) {
211+
// came here from the compositionEnd-event
212+
const position = this._editor.getPosition()!;
213+
const model = this._editor.getModel()!;
214+
text = model.getLineContent(position.lineNumber).substr(0, position.column - 1);
215+
}
216+
217+
let lastChar = '';
218+
if (isLowSurrogate(text.charCodeAt(text.length - 1))) {
219+
if (isHighSurrogate(text.charCodeAt(text.length - 2))) {
220+
lastChar = text.substr(text.length - 2);
221+
}
222+
} else {
223+
lastChar = text.charAt(text.length - 1);
224+
}
225+
226+
const supports = supportsByTriggerCharacter.get(lastChar);
210227
if (supports) {
211228
// keep existing items that where not computed by the
212229
// supports/providers that want to trigger now
213230
const items: CompletionItem[] | undefined = this._completionModel ? this._completionModel.adopt(supports) : undefined;
214231
this.trigger({ auto: true, shy: false, triggerCharacter: lastChar }, Boolean(this._completionModel), supports, items);
215232
}
216-
});
233+
};
234+
235+
this._triggerCharacterListener.add(this._editor.onDidType(checkTriggerCharacter));
236+
this._triggerCharacterListener.add(this._editor.onCompositionEnd(checkTriggerCharacter));
217237
}
218238

219239
// --- trigger/retrigger/cancel suggest

0 commit comments

Comments
 (0)