[cm6] Consolidate loose extensions (#13086)

GitOrigin-RevId: ff937418be5092b2b5197435e9cd60bc61f41b2c
This commit is contained in:
Alf Eaton 2023-05-16 13:16:14 +01:00 committed by Copybot
parent e7b33415a1
commit 60370d5227
9 changed files with 102 additions and 113 deletions

View file

@ -1,19 +1,16 @@
import { keymap } from '@codemirror/view'
import { foldAll, toggleFold, unfoldAll } from '@codemirror/language'
export function foldingKeymap() {
return keymap.of([
{
key: 'F2',
run: toggleFold,
},
{
key: 'Alt-Shift-1',
run: foldAll,
},
{
key: 'Alt-Shift-0',
run: unfoldAll,
},
])
}
export const foldingKeymap = [
{
key: 'F2',
run: toggleFold,
},
{
key: 'Alt-Shift-1',
run: foldAll,
},
{
key: 'Alt-Shift-0',
run: unfoldAll,
},
]

View file

@ -5,7 +5,7 @@ import { updateHasEffect } from '../utils/effects'
const fontLoadEffect = StateEffect.define<readonly FontFace[]>()
export const hasFontLoadedEffect = updateHasEffect(fontLoadEffect)
const plugin = ViewPlugin.define(view => {
export const fontLoad = ViewPlugin.define(view => {
function listener(this: FontFaceSet, event: FontFaceSetLoadEvent) {
view.dispatch({ effects: fontLoadEffect.of(event.fontfaces) })
}
@ -27,7 +27,3 @@ const plugin = ViewPlugin.define(view => {
},
}
})
export function fontLoad() {
return plugin
}

View file

@ -1,7 +1,6 @@
import {
EditorView,
highlightSpecialChars,
keymap,
rectangularSelection,
tooltips,
crosshairCursor,
@ -10,8 +9,7 @@ import {
} from '@codemirror/view'
import { EditorState, Extension } from '@codemirror/state'
import { foldGutter, indentOnInput } from '@codemirror/language'
import { history, historyKeymap, defaultKeymap } from '@codemirror/commands'
import { lintKeymap } from '@codemirror/lint'
import { history } from '@codemirror/commands'
import { language } from './language'
import { lineWrappingIndentation } from './line-wrapping-indentation'
import { theme } from './theme'
@ -25,7 +23,6 @@ import { editable } from './editable'
import { autoPair } from './auto-pair'
import { phrases } from './phrases'
import { spelling } from './spelling'
import { shortcuts } from './shortcuts'
import { symbolPalette } from './symbol-palette'
import { trackChanges } from './track-changes'
import { search } from './search'
@ -40,33 +37,13 @@ import { highlightActiveLine } from './highlight-active-line'
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
import { emptyLineFiller } from './empty-line-filler'
import { goToLinePanel } from './go-to-line'
import { parserWatcher } from './wait-for-parser'
import { drawSelection } from './draw-selection'
import { sourceOnly, visual } from './visual/visual'
import { scrollOneLine } from './scroll-one-line'
import { foldingKeymap } from './folding-keymap'
import { inlineBackground } from './inline-background'
import { fontLoad } from './font-load'
import { indentationMarkers } from './indentation-markers'
import { codemirrorDevTools } from '../languages/latex/codemirror-dev-tools'
const ignoredDefaultKeybindings = new Set([
// NOTE: disable "Mod-Enter" as it's used for "Compile"
'Mod-Enter',
// Disable Alt+Arrow as we have special behaviour on Windows / Linux
'Alt-ArrowLeft',
'Alt-ArrowRight',
// This keybinding causes issues on some keyboard layouts where \ is entered
// using AltGr. Windows treats Ctrl-Alt as AltGr, so trying to insert a \
// with Ctrl-Alt would trigger this keybinding, rather than inserting a \
'Mod-Alt-\\',
])
const ignoredDefaultMacKeybindings = new Set([
// We replace these with our custom visual-line versions
'Mod-Backspace',
'Mod-Delete',
])
import { keymaps } from './keymaps'
import { shortcuts } from './shortcuts'
const moduleExtensions: Array<() => Extension> = importOverleafModules(
'sourceEditorExtensions'
@ -103,24 +80,7 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
tooltips({
parent: document.body,
}),
keymap.of([
...defaultKeymap.filter(
// We only filter on keys, so if the keybinding doesn't have a key,
// allow it
item => {
if (item.key && ignoredDefaultKeybindings.has(item.key)) {
return false
}
if (item.mac && ignoredDefaultMacKeybindings.has(item.mac)) {
return false
}
return true
}
),
...historyKeymap,
...lintKeymap,
]),
foldingKeymap(),
keymaps,
goToLinePanel(),
filterCharacters(),
@ -143,9 +103,8 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
editable(),
search(),
phrases(options.phrases),
parserWatcher(),
spelling(options.spelling),
shortcuts(),
shortcuts,
symbolPalette(),
emptyLineFiller(), // NOTE: must be before `trackChanges`
trackChanges(options.currentDoc, options.changeManager),
@ -153,8 +112,6 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
verticalOverflow(),
highlightActiveLine(options.visual.visual),
highlightActiveLineGutter(),
scrollOneLine(),
fontLoad(),
inlineBackground(options.visual.visual),
codemirrorDevTools(),
exceptionLogger(),

View file

@ -4,7 +4,7 @@ import { themeOptionsChange } from './theme'
import { sourceOnly } from './visual/visual'
import { round } from 'lodash'
import { hasLanguageLoadedEffect } from './language'
import { hasFontLoadedEffect } from './font-load'
import { fontLoad, hasFontLoadedEffect } from './font-load'
const themeConf = new Compartment()
const changeHalfLeadingAnnotation = Annotation.define<boolean>()
@ -92,5 +92,5 @@ const plugin = ViewPlugin.define(
)
export const inlineBackground = (visual: boolean) => {
return sourceOnly(visual, plugin)
return sourceOnly(visual, [fontLoad, plugin])
}

View file

@ -0,0 +1,45 @@
import { keymap } from '@codemirror/view'
import { defaultKeymap, historyKeymap } from '@codemirror/commands'
import { lintKeymap } from '@codemirror/lint'
import { scrollOneLineKeymap } from './scroll-one-line'
import { foldingKeymap } from './folding-keymap'
const ignoredDefaultKeybindings = new Set([
// NOTE: disable "Mod-Enter" as it's used for "Compile"
'Mod-Enter',
// Disable Alt+Arrow as we have special behaviour on Windows / Linux
'Alt-ArrowLeft',
'Alt-ArrowRight',
// This keybinding causes issues on some keyboard layouts where \ is entered
// using AltGr. Windows treats Ctrl-Alt as AltGr, so trying to insert a \
// with Ctrl-Alt would trigger this keybinding, rather than inserting a \
'Mod-Alt-\\',
])
const ignoredDefaultMacKeybindings = new Set([
// We replace these with our custom visual-line versions
'Mod-Backspace',
'Mod-Delete',
])
const filteredDefaultKeymap = defaultKeymap.filter(
// We only filter on keys, so if the keybinding doesn't have a key,
// allow it
item => {
if (item.key && ignoredDefaultKeybindings.has(item.key)) {
return false
}
if (item.mac && ignoredDefaultMacKeybindings.has(item.mac)) {
return false
}
return true
}
)
export const keymaps = keymap.of([
...filteredDefaultKeymap,
...historyKeymap,
...lintKeymap,
...foldingKeymap,
...scrollOneLineKeymap,
])

View file

@ -1,4 +1,4 @@
import { Command, EditorView, keymap } from '@codemirror/view'
import { Command, EditorView } from '@codemirror/view'
function scrollByLine(view: EditorView, lineCount: number) {
view.scrollDOM.scrollTop += view.defaultLineHeight * lineCount
@ -18,18 +18,16 @@ const scrollDownOneLine: Command = (view: EditorView) => {
return true
}
export function scrollOneLine() {
// Applied to Windows and Linux only
return keymap.of([
{
linux: 'Ctrl-ArrowUp',
win: 'Ctrl-ArrowUp',
run: scrollUpOneLine,
},
{
linux: 'Ctrl-ArrowDown',
win: 'Ctrl-ArrowDown',
run: scrollDownOneLine,
},
])
}
// Applied to Windows and Linux only
export const scrollOneLineKeymap = [
{
linux: 'Ctrl-ArrowUp',
win: 'Ctrl-ArrowUp',
run: scrollUpOneLine,
},
{
linux: 'Ctrl-ArrowDown',
win: 'Ctrl-ArrowDown',
run: scrollDownOneLine,
},
]

View file

@ -1,4 +1,4 @@
import { type KeyBinding, keymap } from '@codemirror/view'
import { keymap } from '@codemirror/view'
import { Prec } from '@codemirror/state'
import { indentMore } from '../commands/indent'
import {
@ -24,23 +24,23 @@ import {
deleteToVisualLineStart,
} from './visual-line-selection'
export const shortcuts = () => {
const toggleReviewPanel = () => {
dispatchEditorEvent('toggle-review-panel')
return true
}
const toggleReviewPanel = () => {
dispatchEditorEvent('toggle-review-panel')
return true
}
const addNewCommentFromKbdShortcut = () => {
dispatchEditorEvent('add-new-comment')
return true
}
const addNewCommentFromKbdShortcut = () => {
dispatchEditorEvent('add-new-comment')
return true
}
const toggleTrackChangesFromKbdShortcut = () => {
dispatchEditorEvent('toggle-track-changes')
return true
}
const toggleTrackChangesFromKbdShortcut = () => {
dispatchEditorEvent('toggle-track-changes')
return true
}
const keyBindings: KeyBinding[] = [
export const shortcuts = Prec.high(
keymap.of([
{
key: 'Tab',
run: indentMore,
@ -191,7 +191,5 @@ export const shortcuts = () => {
mac: 'Cmd-Delete',
run: deleteToVisualLineEnd,
},
]
return Prec.high(keymap.of(keyBindings))
}
])
)

View file

@ -15,6 +15,7 @@ import {
import { addWordToCache, cacheField, removeWordFromCache } from './cache'
import { spellingMenuField } from './context-menu'
import { SpellChecker } from './spellchecker'
import { parserWatcher } from '../wait-for-parser'
const spellCheckLanguageConf = new Compartment()
const spellCheckLanguageFacet = Facet.define<string | undefined>()
@ -39,6 +40,7 @@ export const spelling = ({ spellCheckLanguage }: Options) => {
borderWidth: '0',
},
}),
parserWatcher,
spellCheckLanguageConf.of(spellCheckLanguageFacet.of(spellCheckLanguage)),
spellCheckField,
misspelledWordsField,

View file

@ -14,7 +14,7 @@ type ParserWait = {
resolve: () => void
}
const plugin = ViewPlugin.fromClass(
export const parserWatcher = ViewPlugin.fromClass(
class {
waits: ParserWait[] = []
@ -61,16 +61,12 @@ const plugin = ViewPlugin.fromClass(
}
)
export function parserWatcher() {
return plugin
}
// Returns a promise that is resolved as soon as CM6 reports that the parser is
// ready, up to a specified offset in the document or the end if none is
// specified. CM6 dispatches a transaction after every chunk of parser work
// and the view plugin checks after each, so there is minimal delay
export function waitForParser(view: EditorView, upTo?: UpTo) {
const pluginInstance = view.plugin(plugin)
const pluginInstance = view.plugin(parserWatcher)
if (!pluginInstance) {
throw new Error('No parser watcher view plugin found')
}