refactor selections (#876)
* migrate selection types * extract selection event into selections.ts * move code-mirror selection functions into selections.ts * move more selection logit out of code mirror and engine connection * add selection functions pure * tidy up naming * write a novel about how selections work * final comments
This commit is contained in:
108
src/useStore.ts
108
src/useStore.ts
@ -1,13 +1,8 @@
|
||||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
||||
import {
|
||||
parse,
|
||||
Program,
|
||||
_executor,
|
||||
ProgramMemory,
|
||||
SourceRange,
|
||||
} from './lang/wasm'
|
||||
import { parse, Program, _executor, ProgramMemory } from './lang/wasm'
|
||||
import { Selection, Selections, SelectionRangeTypeMap } from 'lib/selections'
|
||||
import { enginelessExecutor } from './lib/testHelpers'
|
||||
import { EditorSelection } from '@codemirror/state'
|
||||
import { EngineCommandManager } from './lang/std/engineConnection'
|
||||
@ -15,25 +10,6 @@ import { KCLError } from './lang/errors'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
import { DefaultPlanes } from './wasm-lib/kcl/bindings/DefaultPlanes'
|
||||
|
||||
export type Axis = 'y-axis' | 'x-axis' | 'z-axis'
|
||||
|
||||
export type Selection = {
|
||||
type:
|
||||
| 'default'
|
||||
| 'line-end'
|
||||
| 'line-mid'
|
||||
| 'face'
|
||||
| 'point'
|
||||
| 'edge'
|
||||
| 'line'
|
||||
| 'arc'
|
||||
| 'all'
|
||||
range: SourceRange
|
||||
}
|
||||
export type Selections = {
|
||||
otherSelections: Axis[]
|
||||
codeBasedSelections: Selection[]
|
||||
}
|
||||
export type ToolTip =
|
||||
| 'lineTo'
|
||||
| 'line'
|
||||
@ -74,10 +50,6 @@ export type PaneType =
|
||||
| 'logs'
|
||||
| 'lspMessages'
|
||||
|
||||
export interface SelectionRangeTypeMap {
|
||||
[key: number]: Selection['type']
|
||||
}
|
||||
|
||||
export interface StoreState {
|
||||
editorView: EditorView | null
|
||||
setEditorView: (editorView: EditorView) => void
|
||||
@ -342,79 +314,3 @@ export async function executeAst({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function dispatchCodeMirrorCursor({
|
||||
selections,
|
||||
editorView,
|
||||
}: {
|
||||
selections: Selections
|
||||
editorView: EditorView
|
||||
}): {
|
||||
selectionRangeTypeMap: SelectionRangeTypeMap
|
||||
} {
|
||||
const ranges: ReturnType<typeof EditorSelection.cursor>[] = []
|
||||
const selectionRangeTypeMap: SelectionRangeTypeMap = {}
|
||||
selections.codeBasedSelections.forEach(({ range, type }) => {
|
||||
if (range?.[1]) {
|
||||
ranges.push(EditorSelection.cursor(range[1]))
|
||||
selectionRangeTypeMap[range[1]] = type
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
ranges.length &&
|
||||
editorView.dispatch({
|
||||
selection: EditorSelection.create(
|
||||
ranges,
|
||||
selections.codeBasedSelections.length - 1
|
||||
),
|
||||
})
|
||||
})
|
||||
return {
|
||||
selectionRangeTypeMap,
|
||||
}
|
||||
}
|
||||
|
||||
export function setCodeMirrorCursor({
|
||||
codeSelection,
|
||||
currestSelections,
|
||||
editorView,
|
||||
isShiftDown,
|
||||
}: {
|
||||
codeSelection?: Selection
|
||||
currestSelections: Selections
|
||||
editorView: EditorView
|
||||
isShiftDown: boolean
|
||||
}): SelectionRangeTypeMap {
|
||||
// This DOES NOT set the `selectionRanges` in xstate context
|
||||
// instead it updates/dispatches to the editor, which in turn updates the xstate context
|
||||
// I've found this the best way to deal with the editor without causing an infinite loop
|
||||
// and really we want the editor to be in charge of cursor positions and for `selectionRanges` mirror it
|
||||
// because we want to respect the user manually placing the cursor too.
|
||||
const code = kclManager.code
|
||||
if (!codeSelection) {
|
||||
const { selectionRangeTypeMap } = dispatchCodeMirrorCursor({
|
||||
editorView,
|
||||
selections: {
|
||||
otherSelections: currestSelections.otherSelections,
|
||||
codeBasedSelections: [
|
||||
{
|
||||
range: [0, code.length ? code.length - 1 : 0],
|
||||
type: 'default',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
return selectionRangeTypeMap
|
||||
}
|
||||
const selections: Selections = {
|
||||
...currestSelections,
|
||||
codeBasedSelections: isShiftDown
|
||||
? [...currestSelections.codeBasedSelections, codeSelection]
|
||||
: [codeSelection],
|
||||
}
|
||||
const { selectionRangeTypeMap } = dispatchCodeMirrorCursor({
|
||||
editorView,
|
||||
selections,
|
||||
})
|
||||
return selectionRangeTypeMap
|
||||
}
|
||||
|
Reference in New Issue
Block a user