Skip to content

Commit

Permalink
Add activateOnTypingDelay option
Browse files Browse the repository at this point in the history
FEATURE: The new `activateOnTypingDelay` option allows control over the debounce
time before the completions are queried when the user types.

Closes #20
  • Loading branch information
marijnh committed Jan 12, 2024
1 parent 0b6faf9 commit 10d1e88
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ export interface CompletionConfig {
/// When enabled (defaults to true), autocompletion will start
/// whenever the user types something that can be completed.
activateOnTyping?: boolean
/// The amount of time to wait for further typing before querying
/// completion sources via
/// [`activateOnTyping`](#autocomplete.autocompletion^config.activateOnTyping).
/// Defaults to 100, which should be fine unless your completion
/// source is very slow and/or doesn't use `validFor`.
activateOnTypingDelay?: number
/// By default, when completion opens, the first option is selected
/// and can be confirmed with
/// [`acceptCompletion`](#autocomplete.acceptCompletion). When this
Expand Down Expand Up @@ -82,6 +88,7 @@ export const completionConfig = Facet.define<CompletionConfig, Required<Completi
combine(configs) {
return combineConfig<Required<CompletionConfig>>(configs, {
activateOnTyping: true,
activateOnTypingDelay: 100,
selectOnOpen: true,
override: null,
closeOnBlur: true,
Expand Down
6 changes: 5 additions & 1 deletion src/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const completionPlugin = ViewPlugin.fromClass(class implements PluginValu
debounceUpdate = -1
running: RunningQuery[] = []
debounceAccept = -1
pendingStart = false
composing = CompositionState.None

constructor(readonly view: EditorView) {
Expand Down Expand Up @@ -102,8 +103,10 @@ export const completionPlugin = ViewPlugin.fromClass(class implements PluginValu
}

if (this.debounceUpdate > -1) clearTimeout(this.debounceUpdate)
if (update.transactions.some(tr => tr.effects.some(e => e.is(startCompletionEffect)))) this.pendingStart = true
let delay = this.pendingStart ? 50 : update.state.facet(completionConfig).activateOnTypingDelay
this.debounceUpdate = cState.active.some(a => a.state == State.Pending && !this.running.some(q => q.active.source == a.source))
? setTimeout(() => this.startUpdate(), 50) : -1
? setTimeout(() => this.startUpdate(), delay) : -1

if (this.composing != CompositionState.None) for (let tr of update.transactions) {
if (getUserEvent(tr) == "input")
Expand All @@ -115,6 +118,7 @@ export const completionPlugin = ViewPlugin.fromClass(class implements PluginValu

startUpdate() {
this.debounceUpdate = -1
this.pendingStart = false
let {state} = this.view, cState = state.field(completionState)
for (let active of cState.active) {
if (active.state == State.Pending && !this.running.some(r => r.active.source == active.source))
Expand Down
5 changes: 4 additions & 1 deletion test/webtest-autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ class Runner {
state: EditorState.create({
doc: spec.doc,
selection,
extensions: [autocompletion({override: spec.sources, interactionDelay: 0, updateSyncTime: 40}), EditorState.allowMultipleSelections.of(true)]
extensions: [
autocompletion({override: spec.sources, interactionDelay: 0, updateSyncTime: 40, activateOnTypingDelay: 10}),
EditorState.allowMultipleSelections.of(true)
]
}),
parent: document.querySelector("#workspace")! as HTMLElement,
dispatchTransactions: trs => {
Expand Down

0 comments on commit 10d1e88

Please sign in to comment.