Skip to content

Commit 90412d8

Browse files
committed
Respond to clicks on the top/bottom of incomplete option lists by moving selection
FIX: Clicking the horizontal dots at the top/bottom of a list of completion options now moves the selection there, so that more completions become visible. See https://discuss.codemirror.net/t/autocomplete-list-show-more-not-clickable/9627
1 parent e8521c2 commit 90412d8

File tree

4 files changed

+19
-6
lines changed

4 files changed

+19
-6
lines changed

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {Prec, Extension, EditorState, StateEffect} from "@codemirror/state"
22
import {keymap, KeyBinding} from "@codemirror/view"
33
import {Completion, Option} from "./completion"
4-
import {completionState, State, setSelectedEffect} from "./state"
4+
import {completionState, State} from "./state"
5+
import {setSelectedEffect} from "./tooltip"
56
import {CompletionConfig, completionConfig} from "./config"
67
import {completionPlugin, moveCompletionSelection, acceptCompletion,
78
startCompletion, closeCompletion, commitCharacters} from "./view"

src/state.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {Option, CompletionSource, CompletionResult, cur, asSource,
55
startCompletionEffect, closeCompletionEffect,
66
insertCompletionText, pickedCompletion} from "./completion"
77
import {FuzzyMatcher, StrictMatcher} from "./filter"
8-
import {completionTooltip} from "./tooltip"
8+
import {completionTooltip, setSelectedEffect} from "./tooltip"
99
import {CompletionConfig, completionConfig} from "./config"
1010

1111
// Used to pick a preferred option when two options with the same
@@ -316,7 +316,6 @@ function checkValid(validFor: undefined | RegExp | ((text: string, from: number,
316316
export const setActiveEffect = StateEffect.define<readonly ActiveSource[]>({
317317
map(sources, mapping) { return sources.map(s => s.map(mapping)) }
318318
})
319-
export const setSelectedEffect = StateEffect.define<number>()
320319

321320
export const completionState = StateField.define<CompletionState>({
322321
create() { return CompletionState.start() },

src/tooltip.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import {EditorView, ViewUpdate, logException, TooltipView, Rect} from "@codemirror/view"
2-
import {StateField, EditorState} from "@codemirror/state"
2+
import {StateField, StateEffect, EditorState} from "@codemirror/state"
33
import {CompletionState} from "./state"
44
import {completionConfig, CompletionConfig} from "./config"
55
import {Option, Completion, CompletionInfo, closeCompletionEffect} from "./completion"
66

7+
export const setSelectedEffect = StateEffect.define<number>()
8+
79
type OptionContentSource =
810
(completion: Completion, state: EditorState, view: EditorView, match: readonly number[]) => Node | null
911

@@ -102,6 +104,16 @@ class CompletionTooltip {
102104
return
103105
}
104106
}
107+
if (e.target == this.list) {
108+
let move = this.list.classList.contains("cm-completionListIncompleteTop") &&
109+
e.clientY < (this.list.firstChild as HTMLElement).getBoundingClientRect().top ? this.range.from - 1 :
110+
this.list.classList.contains("cm-completionListIncompleteBottom") &&
111+
e.clientY > (this.list.lastChild as HTMLElement).getBoundingClientRect().bottom ? this.range.to : null
112+
if (move != null) {
113+
view.dispatch({effects: setSelectedEffect.of(move)})
114+
e.preventDefault()
115+
}
116+
}
105117
})
106118
this.dom.addEventListener("focusout", (e: FocusEvent) => {
107119
let state = view.state.field(this.stateField, false)
@@ -129,7 +141,7 @@ class CompletionTooltip {
129141
if (cState != prevState) {
130142
let {options, selected, disabled} = cState.open!
131143
if (!prevState.open || prevState.open.options != options) {
132-
this.range = rangeAroundSelected(options.length, selected, update.state.facet(completionConfig).maxRenderedOptions)
144+
this.range = rangeAroundSelected(options.length, selected, update.state.facet(completionConfig).maxRenderedOptions)
133145
this.showOptions(options, cState.id)
134146
}
135147
this.updateSel()

src/view.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import {EditorView, Command, ViewPlugin, PluginValue, ViewUpdate, logException,
22
getTooltip, TooltipView} from "@codemirror/view"
33
import {Transaction, Prec} from "@codemirror/state"
4-
import {completionState, setSelectedEffect, setActiveEffect, State,
4+
import {completionState, setActiveEffect, State,
55
ActiveSource, ActiveResult, getUpdateType, UpdateType, applyCompletion} from "./state"
6+
import {setSelectedEffect} from "./tooltip"
67
import {completionConfig} from "./config"
78
import {cur, CompletionResult, CompletionContext, startCompletionEffect, closeCompletionEffect} from "./completion"
89

0 commit comments

Comments
 (0)