mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
[cm6] Consolidate loose extensions (#13086)
GitOrigin-RevId: ff937418be5092b2b5197435e9cd60bc61f41b2c
This commit is contained in:
parent
e7b33415a1
commit
60370d5227
9 changed files with 102 additions and 113 deletions
|
@ -1,19 +1,16 @@
|
||||||
import { keymap } from '@codemirror/view'
|
|
||||||
import { foldAll, toggleFold, unfoldAll } from '@codemirror/language'
|
import { foldAll, toggleFold, unfoldAll } from '@codemirror/language'
|
||||||
|
|
||||||
export function foldingKeymap() {
|
export const foldingKeymap = [
|
||||||
return keymap.of([
|
{
|
||||||
{
|
key: 'F2',
|
||||||
key: 'F2',
|
run: toggleFold,
|
||||||
run: toggleFold,
|
},
|
||||||
},
|
{
|
||||||
{
|
key: 'Alt-Shift-1',
|
||||||
key: 'Alt-Shift-1',
|
run: foldAll,
|
||||||
run: foldAll,
|
},
|
||||||
},
|
{
|
||||||
{
|
key: 'Alt-Shift-0',
|
||||||
key: 'Alt-Shift-0',
|
run: unfoldAll,
|
||||||
run: unfoldAll,
|
},
|
||||||
},
|
]
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { updateHasEffect } from '../utils/effects'
|
||||||
const fontLoadEffect = StateEffect.define<readonly FontFace[]>()
|
const fontLoadEffect = StateEffect.define<readonly FontFace[]>()
|
||||||
export const hasFontLoadedEffect = updateHasEffect(fontLoadEffect)
|
export const hasFontLoadedEffect = updateHasEffect(fontLoadEffect)
|
||||||
|
|
||||||
const plugin = ViewPlugin.define(view => {
|
export const fontLoad = ViewPlugin.define(view => {
|
||||||
function listener(this: FontFaceSet, event: FontFaceSetLoadEvent) {
|
function listener(this: FontFaceSet, event: FontFaceSetLoadEvent) {
|
||||||
view.dispatch({ effects: fontLoadEffect.of(event.fontfaces) })
|
view.dispatch({ effects: fontLoadEffect.of(event.fontfaces) })
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,3 @@ const plugin = ViewPlugin.define(view => {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export function fontLoad() {
|
|
||||||
return plugin
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import {
|
import {
|
||||||
EditorView,
|
EditorView,
|
||||||
highlightSpecialChars,
|
highlightSpecialChars,
|
||||||
keymap,
|
|
||||||
rectangularSelection,
|
rectangularSelection,
|
||||||
tooltips,
|
tooltips,
|
||||||
crosshairCursor,
|
crosshairCursor,
|
||||||
|
@ -10,8 +9,7 @@ import {
|
||||||
} from '@codemirror/view'
|
} from '@codemirror/view'
|
||||||
import { EditorState, Extension } from '@codemirror/state'
|
import { EditorState, Extension } from '@codemirror/state'
|
||||||
import { foldGutter, indentOnInput } from '@codemirror/language'
|
import { foldGutter, indentOnInput } from '@codemirror/language'
|
||||||
import { history, historyKeymap, defaultKeymap } from '@codemirror/commands'
|
import { history } from '@codemirror/commands'
|
||||||
import { lintKeymap } from '@codemirror/lint'
|
|
||||||
import { language } from './language'
|
import { language } from './language'
|
||||||
import { lineWrappingIndentation } from './line-wrapping-indentation'
|
import { lineWrappingIndentation } from './line-wrapping-indentation'
|
||||||
import { theme } from './theme'
|
import { theme } from './theme'
|
||||||
|
@ -25,7 +23,6 @@ import { editable } from './editable'
|
||||||
import { autoPair } from './auto-pair'
|
import { autoPair } from './auto-pair'
|
||||||
import { phrases } from './phrases'
|
import { phrases } from './phrases'
|
||||||
import { spelling } from './spelling'
|
import { spelling } from './spelling'
|
||||||
import { shortcuts } from './shortcuts'
|
|
||||||
import { symbolPalette } from './symbol-palette'
|
import { symbolPalette } from './symbol-palette'
|
||||||
import { trackChanges } from './track-changes'
|
import { trackChanges } from './track-changes'
|
||||||
import { search } from './search'
|
import { search } from './search'
|
||||||
|
@ -40,33 +37,13 @@ import { highlightActiveLine } from './highlight-active-line'
|
||||||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||||
import { emptyLineFiller } from './empty-line-filler'
|
import { emptyLineFiller } from './empty-line-filler'
|
||||||
import { goToLinePanel } from './go-to-line'
|
import { goToLinePanel } from './go-to-line'
|
||||||
import { parserWatcher } from './wait-for-parser'
|
|
||||||
import { drawSelection } from './draw-selection'
|
import { drawSelection } from './draw-selection'
|
||||||
import { sourceOnly, visual } from './visual/visual'
|
import { sourceOnly, visual } from './visual/visual'
|
||||||
import { scrollOneLine } from './scroll-one-line'
|
|
||||||
import { foldingKeymap } from './folding-keymap'
|
|
||||||
import { inlineBackground } from './inline-background'
|
import { inlineBackground } from './inline-background'
|
||||||
import { fontLoad } from './font-load'
|
|
||||||
import { indentationMarkers } from './indentation-markers'
|
import { indentationMarkers } from './indentation-markers'
|
||||||
import { codemirrorDevTools } from '../languages/latex/codemirror-dev-tools'
|
import { codemirrorDevTools } from '../languages/latex/codemirror-dev-tools'
|
||||||
|
import { keymaps } from './keymaps'
|
||||||
const ignoredDefaultKeybindings = new Set([
|
import { shortcuts } from './shortcuts'
|
||||||
// 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 moduleExtensions: Array<() => Extension> = importOverleafModules(
|
const moduleExtensions: Array<() => Extension> = importOverleafModules(
|
||||||
'sourceEditorExtensions'
|
'sourceEditorExtensions'
|
||||||
|
@ -103,24 +80,7 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
|
||||||
tooltips({
|
tooltips({
|
||||||
parent: document.body,
|
parent: document.body,
|
||||||
}),
|
}),
|
||||||
keymap.of([
|
keymaps,
|
||||||
...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(),
|
|
||||||
goToLinePanel(),
|
goToLinePanel(),
|
||||||
filterCharacters(),
|
filterCharacters(),
|
||||||
|
|
||||||
|
@ -143,9 +103,8 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
|
||||||
editable(),
|
editable(),
|
||||||
search(),
|
search(),
|
||||||
phrases(options.phrases),
|
phrases(options.phrases),
|
||||||
parserWatcher(),
|
|
||||||
spelling(options.spelling),
|
spelling(options.spelling),
|
||||||
shortcuts(),
|
shortcuts,
|
||||||
symbolPalette(),
|
symbolPalette(),
|
||||||
emptyLineFiller(), // NOTE: must be before `trackChanges`
|
emptyLineFiller(), // NOTE: must be before `trackChanges`
|
||||||
trackChanges(options.currentDoc, options.changeManager),
|
trackChanges(options.currentDoc, options.changeManager),
|
||||||
|
@ -153,8 +112,6 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
|
||||||
verticalOverflow(),
|
verticalOverflow(),
|
||||||
highlightActiveLine(options.visual.visual),
|
highlightActiveLine(options.visual.visual),
|
||||||
highlightActiveLineGutter(),
|
highlightActiveLineGutter(),
|
||||||
scrollOneLine(),
|
|
||||||
fontLoad(),
|
|
||||||
inlineBackground(options.visual.visual),
|
inlineBackground(options.visual.visual),
|
||||||
codemirrorDevTools(),
|
codemirrorDevTools(),
|
||||||
exceptionLogger(),
|
exceptionLogger(),
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { themeOptionsChange } from './theme'
|
||||||
import { sourceOnly } from './visual/visual'
|
import { sourceOnly } from './visual/visual'
|
||||||
import { round } from 'lodash'
|
import { round } from 'lodash'
|
||||||
import { hasLanguageLoadedEffect } from './language'
|
import { hasLanguageLoadedEffect } from './language'
|
||||||
import { hasFontLoadedEffect } from './font-load'
|
import { fontLoad, hasFontLoadedEffect } from './font-load'
|
||||||
|
|
||||||
const themeConf = new Compartment()
|
const themeConf = new Compartment()
|
||||||
const changeHalfLeadingAnnotation = Annotation.define<boolean>()
|
const changeHalfLeadingAnnotation = Annotation.define<boolean>()
|
||||||
|
@ -92,5 +92,5 @@ const plugin = ViewPlugin.define(
|
||||||
)
|
)
|
||||||
|
|
||||||
export const inlineBackground = (visual: boolean) => {
|
export const inlineBackground = (visual: boolean) => {
|
||||||
return sourceOnly(visual, plugin)
|
return sourceOnly(visual, [fontLoad, plugin])
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
])
|
|
@ -1,4 +1,4 @@
|
||||||
import { Command, EditorView, keymap } from '@codemirror/view'
|
import { Command, EditorView } from '@codemirror/view'
|
||||||
|
|
||||||
function scrollByLine(view: EditorView, lineCount: number) {
|
function scrollByLine(view: EditorView, lineCount: number) {
|
||||||
view.scrollDOM.scrollTop += view.defaultLineHeight * lineCount
|
view.scrollDOM.scrollTop += view.defaultLineHeight * lineCount
|
||||||
|
@ -18,18 +18,16 @@ const scrollDownOneLine: Command = (view: EditorView) => {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scrollOneLine() {
|
// Applied to Windows and Linux only
|
||||||
// Applied to Windows and Linux only
|
export const scrollOneLineKeymap = [
|
||||||
return keymap.of([
|
{
|
||||||
{
|
linux: 'Ctrl-ArrowUp',
|
||||||
linux: 'Ctrl-ArrowUp',
|
win: 'Ctrl-ArrowUp',
|
||||||
win: 'Ctrl-ArrowUp',
|
run: scrollUpOneLine,
|
||||||
run: scrollUpOneLine,
|
},
|
||||||
},
|
{
|
||||||
{
|
linux: 'Ctrl-ArrowDown',
|
||||||
linux: 'Ctrl-ArrowDown',
|
win: 'Ctrl-ArrowDown',
|
||||||
win: 'Ctrl-ArrowDown',
|
run: scrollDownOneLine,
|
||||||
run: scrollDownOneLine,
|
},
|
||||||
},
|
]
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { type KeyBinding, keymap } from '@codemirror/view'
|
import { keymap } from '@codemirror/view'
|
||||||
import { Prec } from '@codemirror/state'
|
import { Prec } from '@codemirror/state'
|
||||||
import { indentMore } from '../commands/indent'
|
import { indentMore } from '../commands/indent'
|
||||||
import {
|
import {
|
||||||
|
@ -24,23 +24,23 @@ import {
|
||||||
deleteToVisualLineStart,
|
deleteToVisualLineStart,
|
||||||
} from './visual-line-selection'
|
} from './visual-line-selection'
|
||||||
|
|
||||||
export const shortcuts = () => {
|
const toggleReviewPanel = () => {
|
||||||
const toggleReviewPanel = () => {
|
dispatchEditorEvent('toggle-review-panel')
|
||||||
dispatchEditorEvent('toggle-review-panel')
|
return true
|
||||||
return true
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const addNewCommentFromKbdShortcut = () => {
|
const addNewCommentFromKbdShortcut = () => {
|
||||||
dispatchEditorEvent('add-new-comment')
|
dispatchEditorEvent('add-new-comment')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleTrackChangesFromKbdShortcut = () => {
|
const toggleTrackChangesFromKbdShortcut = () => {
|
||||||
dispatchEditorEvent('toggle-track-changes')
|
dispatchEditorEvent('toggle-track-changes')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyBindings: KeyBinding[] = [
|
export const shortcuts = Prec.high(
|
||||||
|
keymap.of([
|
||||||
{
|
{
|
||||||
key: 'Tab',
|
key: 'Tab',
|
||||||
run: indentMore,
|
run: indentMore,
|
||||||
|
@ -191,7 +191,5 @@ export const shortcuts = () => {
|
||||||
mac: 'Cmd-Delete',
|
mac: 'Cmd-Delete',
|
||||||
run: deleteToVisualLineEnd,
|
run: deleteToVisualLineEnd,
|
||||||
},
|
},
|
||||||
]
|
])
|
||||||
|
)
|
||||||
return Prec.high(keymap.of(keyBindings))
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
import { addWordToCache, cacheField, removeWordFromCache } from './cache'
|
import { addWordToCache, cacheField, removeWordFromCache } from './cache'
|
||||||
import { spellingMenuField } from './context-menu'
|
import { spellingMenuField } from './context-menu'
|
||||||
import { SpellChecker } from './spellchecker'
|
import { SpellChecker } from './spellchecker'
|
||||||
|
import { parserWatcher } from '../wait-for-parser'
|
||||||
|
|
||||||
const spellCheckLanguageConf = new Compartment()
|
const spellCheckLanguageConf = new Compartment()
|
||||||
const spellCheckLanguageFacet = Facet.define<string | undefined>()
|
const spellCheckLanguageFacet = Facet.define<string | undefined>()
|
||||||
|
@ -39,6 +40,7 @@ export const spelling = ({ spellCheckLanguage }: Options) => {
|
||||||
borderWidth: '0',
|
borderWidth: '0',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
parserWatcher,
|
||||||
spellCheckLanguageConf.of(spellCheckLanguageFacet.of(spellCheckLanguage)),
|
spellCheckLanguageConf.of(spellCheckLanguageFacet.of(spellCheckLanguage)),
|
||||||
spellCheckField,
|
spellCheckField,
|
||||||
misspelledWordsField,
|
misspelledWordsField,
|
||||||
|
|
|
@ -14,7 +14,7 @@ type ParserWait = {
|
||||||
resolve: () => void
|
resolve: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const plugin = ViewPlugin.fromClass(
|
export const parserWatcher = ViewPlugin.fromClass(
|
||||||
class {
|
class {
|
||||||
waits: ParserWait[] = []
|
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
|
// 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
|
// 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
|
// specified. CM6 dispatches a transaction after every chunk of parser work
|
||||||
// and the view plugin checks after each, so there is minimal delay
|
// and the view plugin checks after each, so there is minimal delay
|
||||||
export function waitForParser(view: EditorView, upTo?: UpTo) {
|
export function waitForParser(view: EditorView, upTo?: UpTo) {
|
||||||
const pluginInstance = view.plugin(plugin)
|
const pluginInstance = view.plugin(parserWatcher)
|
||||||
if (!pluginInstance) {
|
if (!pluginInstance) {
|
||||||
throw new Error('No parser watcher view plugin found')
|
throw new Error('No parser watcher view plugin found')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue