Skip to content

Commit

Permalink
feat(completion): try trigger completion without filtered
Browse files Browse the repository at this point in the history
  • Loading branch information
chemzqm committed Oct 19, 2022
1 parent adc9be8 commit 33c075c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 19 deletions.
4 changes: 4 additions & 0 deletions history.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 2022-10-19

- Trigger for trigger sources when no filter results available.

# 2022-10-18

- Change `suggest.maxCompleteItemCount` default to 256.
Expand Down
28 changes: 26 additions & 2 deletions src/__tests__/completion/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,31 @@ describe('completion', () => {
expect(completion.activeItems.length).toBe(1)
})

it('should trigger for trigger character when filter failed', async () => {
await nvim.command('edit t|setl iskeyword=@,-')
let doc = await workspace.document
expect(doc.chars.isKeywordChar('-')).toBe(true)
let source: ISource = {
name: 'dash',
enable: true,
sourceType: SourceType.Service,
triggerCharacters: ['-'],
doComplete: async (opt: CompleteOption): Promise<CompleteResult> => {
if (opt.triggerCharacter == '-') return { items: [{ word: '-foo' }] }
return { items: [{ word: 'foo' }, { word: 'bar' }] }
}
}
disposables.push(sources.addSource(source))
await nvim.input('i')
await triggerCompletion('dash')
await helper.waitPopup()
await nvim.input('-')
await helper.waitValue(() => {
let items = completion.activeItems
return items && items.length == 1 && items[0].word == '-foo'
}, true)
})

it('should trigger on trigger character', async () => {
helper.updateConfiguration('suggest.autoTrigger', 'trigger')
let fn = jest.fn()
Expand Down Expand Up @@ -774,15 +799,14 @@ describe('completion', () => {

it('should not trigger when document not attached', async () => {
await nvim.command('edit t|setl buftype=nofile')
await nvim.setLine('foo ')
await nvim.input('o')
await helper.wait(10)
expect(completion.isActivated).toBe(false)
})
})

describe('trigger completion', () => {
it('should trigger complete on trigger patterns match', async () => {
it('should trigger complete when trigger patterns match', async () => {
let source: ISource = {
priority: 99,
enable: true,
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/modules/chars.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ describe('IntegerRanges', () => {
expect(r.includes(9)).toBe(true)
r = IntegerRanges.fromKeywordOption('65,-x,x-')
expect(r.includes(65)).toBe(true)
r = IntegerRanges.fromKeywordOption('128-140,-')
expect(r.includes('-'.charCodeAt(0))).toBe(true)
})
})

Expand Down
8 changes: 4 additions & 4 deletions src/completion/complete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ export default class Complete {
let timer: NodeJS.Timer
let tp = new Promise<void>(resolve => {
timer = setTimeout(() => {
if (!tokenSource.token.isCancellationRequested) {
if (!token.isCancellationRequested) {
names = names.filter(n => !finished.includes(n))
tokenSource.cancel()
logger.warn(`Complete timeout after ${timeout}ms`, names)
logger.warn(`Completion timeout after ${timeout}ms`, names)
this.nvim.setVar(`coc_timeout_sources`, names, true)
}
resolve()
Expand Down Expand Up @@ -307,7 +307,7 @@ export default class Complete {
}

public async filterResults(input: string): Promise<ExtendedCompleteItem[] | undefined> {
if (this.timer) clearTimeout(this.timer)
clearTimeout(this.timer)
if (input !== this.option.input) {
let names = this.getIncompleteSources()
if (names.length) {
Expand Down Expand Up @@ -350,7 +350,7 @@ export default class Complete {
}
}

private cancel(): void {
public cancel(): void {
let { tokenSource, timer } = this
if (timer) clearTimeout(timer)
tokenSource.cancel()
Expand Down
36 changes: 26 additions & 10 deletions src/completion/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import sources from '../sources'
import { CompleteOption, ExtendedCompleteItem, IConfigurationChangeEvent, ISource } from '../types'
import { disposeAll } from '../util'
import { isFalsyOrEmpty } from '../util/array'
import { byteLength, byteSlice, characterIndex, isWord } from '../util/string'
import { byteLength, byteSlice, characterIndex } from '../util/string'
import window from '../window'
import workspace from '../workspace'
import Complete, { CompleteConfig } from './complete'
Expand Down Expand Up @@ -201,14 +201,17 @@ export class Completion implements Disposable {
}

private async onTextChangedP(bufnr: number, info: InsertChange): Promise<void> {
if (this.option && bufnr === this.option.bufnr) {
this.pretext = info.pre
if (bufnr !== this.option?.bufnr) return
// navigate item or finish completion
if (!info.insertChar && this.complete) {
this.complete.cancel()
}
this.pretext = info.pre
}

private async onTextChangedI(bufnr: number, info: InsertChange): Promise<void> {
const doc = workspace.getDocument(bufnr)
if (!doc.attached) return
if (!doc || !doc.attached) return
const { option } = this
if (option != null) {
// detect item word insert
Expand Down Expand Up @@ -257,9 +260,8 @@ export class Completion implements Disposable {
}
}
// trigger character
if (!isWord(info.insertChar)) {
let disabled = doc.getVar('disabled_sources', [])
let triggerSources = sources.getTriggerSources(pretext, doc.filetype, doc.uri, disabled)
if (!doc.chars.isKeywordChar(info.insertChar)) {
let triggerSources = this.getTriggerSources(doc, pretext)
if (triggerSources.length > 0) {
await this.triggerCompletion(doc, info, triggerSources)
return
Expand All @@ -277,7 +279,12 @@ export class Completion implements Disposable {
}, global.__TEST__ ? 20 : 200)
return
}
await this.filterResults()
await this.filterResults(info)
}

private getTriggerSources(doc: Document, pretext: string): ISource[] {
let disabled = doc.getVar('disabled_sources', [])
return sources.getTriggerSources(pretext, doc.filetype, doc.uri, disabled)
}

private async triggerCompletion(doc: Document, info: InsertChange, sources?: ISource[]): Promise<boolean> {
Expand Down Expand Up @@ -363,16 +370,25 @@ export class Completion implements Disposable {
return true
}

private async filterResults(): Promise<void> {
private async filterResults(info?: InsertChange): Promise<void> {
let { complete, option, pretext } = this
let search = getResumeInput(option, pretext)
if (search == null) {
this.stop(true)
return
}
let items = await complete.filterResults(search)
// cancelled
// cancelled or have inserted text
if (items === undefined || this.inserted) return
// trigger completion when trigger source available
if (info && option && items.length == 0) {
let doc = workspace.getDocument(option.bufnr)
let triggerSources = this.getTriggerSources(doc, pretext)
if (triggerSources.length > 0) {
await this.triggerCompletion(doc, info, triggerSources)
return
}
}
if (items.length == 0 || !this.option) {
if (!complete.isCompleting) this.stop(true)
return
Expand Down
4 changes: 1 addition & 3 deletions src/sources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,7 @@ export class Sources {
return this.sources.filter(source => {
let { filetypes, enable, documentSelector, name } = source
if (disabled.includes(name)) return false
if (!enable || (filetypes && !intersect(filetypes, languageIds))) {
return false
}
if (!enable || (filetypes && !intersect(filetypes, languageIds))) return false
if (documentSelector && languageIds.every(languageId => workspace.match(documentSelector, { uri, languageId }) == 0)) {
return false
}
Expand Down

0 comments on commit 33c075c

Please sign in to comment.