Merge pull request #12696 from overleaf/mj-rt-skip-more-preamble
[cm6+rt] Update skip-preamble-cursor to skip \maketitle and abstract GitOrigin-RevId: 3c54d8159bfdb431763872790a2b82ac4cffc09f
This commit is contained in:
committed by
Copybot
parent
59b3b9b933
commit
3bd174631a
+17
-17
@@ -731,6 +731,23 @@ export const atomicDecorations = (options: Options) => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (nodeRef.type.is('Maketitle')) {
|
||||||
|
if (shouldDecorate(state, nodeRef)) {
|
||||||
|
const line = state.doc.lineAt(nodeRef.from)
|
||||||
|
const from = extendBackwardsOverEmptyLines(state.doc, line)
|
||||||
|
const to = extendForwardsOverEmptyLines(state.doc, line)
|
||||||
|
|
||||||
|
if (shouldDecorate(state, { from, to })) {
|
||||||
|
decorations.push(
|
||||||
|
Decoration.replace({
|
||||||
|
widget: new MakeTitleWidget(preamble),
|
||||||
|
block: true,
|
||||||
|
}).range(from, to)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
} else if (nodeRef.type.is('Item')) {
|
} else if (nodeRef.type.is('Item')) {
|
||||||
// only decorate \item inside a list
|
// only decorate \item inside a list
|
||||||
if (currentListEnvironment) {
|
if (currentListEnvironment) {
|
||||||
@@ -823,23 +840,6 @@ export const atomicDecorations = (options: Options) => {
|
|||||||
widget: new TeXWidget(),
|
widget: new TeXWidget(),
|
||||||
}).range(nodeRef.from, nodeRef.to)
|
}).range(nodeRef.from, nodeRef.to)
|
||||||
)
|
)
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else if (commandName === '\\maketitle') {
|
|
||||||
if (shouldDecorate(state, nodeRef)) {
|
|
||||||
const line = state.doc.lineAt(nodeRef.from)
|
|
||||||
const from = extendBackwardsOverEmptyLines(state.doc, line)
|
|
||||||
const to = extendForwardsOverEmptyLines(state.doc, line)
|
|
||||||
|
|
||||||
if (shouldDecorate(state, { from, to })) {
|
|
||||||
decorations.push(
|
|
||||||
Decoration.replace({
|
|
||||||
widget: new MakeTitleWidget(preamble),
|
|
||||||
block: true,
|
|
||||||
}).range(from, to)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else if (hasCharacterSubstitution(commandName)) {
|
} else if (hasCharacterSubstitution(commandName)) {
|
||||||
|
|||||||
+10
-3
@@ -1,7 +1,8 @@
|
|||||||
import { EditorView, ViewPlugin } from '@codemirror/view'
|
import { EditorView, ViewPlugin } from '@codemirror/view'
|
||||||
import { EditorSelection } from '@codemirror/state'
|
import { EditorSelection } from '@codemirror/state'
|
||||||
import { findDocumentEnvironment } from '../../utils/tree-operations/environments'
|
import { findStartOfDocumentContent } from '../../utils/tree-operations/environments'
|
||||||
import { syntaxTree } from '@codemirror/language'
|
import { syntaxTree } from '@codemirror/language'
|
||||||
|
import { extendForwardsOverEmptyLines } from './selection'
|
||||||
export const skipPreambleWithCursor = ViewPlugin.define((view: EditorView) => {
|
export const skipPreambleWithCursor = ViewPlugin.define((view: EditorView) => {
|
||||||
let checkedOnce = false
|
let checkedOnce = false
|
||||||
return {
|
return {
|
||||||
@@ -21,10 +22,16 @@ export const skipPreambleWithCursor = ViewPlugin.define((view: EditorView) => {
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const position = findDocumentEnvironment(view.state)
|
const position =
|
||||||
|
extendForwardsOverEmptyLines(
|
||||||
|
update.state.doc,
|
||||||
|
update.state.doc.lineAt(
|
||||||
|
findStartOfDocumentContent(update.state) ?? 0
|
||||||
|
)
|
||||||
|
) + 1
|
||||||
view.dispatch({
|
view.dispatch({
|
||||||
selection: EditorSelection.cursor(
|
selection: EditorSelection.cursor(
|
||||||
Math.min(position ? position + 1 : 0, update.state.doc.length)
|
Math.min(position, update.state.doc.length)
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|||||||
@@ -84,7 +84,8 @@
|
|||||||
CenteringCtrlSeq,
|
CenteringCtrlSeq,
|
||||||
BibliographyCtrlSeq,
|
BibliographyCtrlSeq,
|
||||||
BibliographyStyleCtrlSeq,
|
BibliographyStyleCtrlSeq,
|
||||||
AuthorCtrlSeq
|
AuthorCtrlSeq,
|
||||||
|
MaketitleCtrlSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
@external specialize {EnvName} specializeEnvName from "./tokens.mjs" {
|
@external specialize {EnvName} specializeEnvName from "./tokens.mjs" {
|
||||||
@@ -310,6 +311,9 @@ KnownCommand {
|
|||||||
} |
|
} |
|
||||||
Item {
|
Item {
|
||||||
ItemCtrlSeq optionalWhitespace?
|
ItemCtrlSeq optionalWhitespace?
|
||||||
|
} |
|
||||||
|
Maketitle {
|
||||||
|
MaketitleCtrlSeq optionalWhitespace?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import {
|
|||||||
BibliographyStyleCtrlSeq,
|
BibliographyStyleCtrlSeq,
|
||||||
CenteringCtrlSeq,
|
CenteringCtrlSeq,
|
||||||
ListEnvName,
|
ListEnvName,
|
||||||
|
MaketitleCtrlSeq,
|
||||||
} from './latex.terms.mjs'
|
} from './latex.terms.mjs'
|
||||||
|
|
||||||
function nameChar(ch) {
|
function nameChar(ch) {
|
||||||
@@ -635,6 +636,7 @@ const otherKnowncommands = {
|
|||||||
'\\centering': CenteringCtrlSeq,
|
'\\centering': CenteringCtrlSeq,
|
||||||
'\\bibliography': BibliographyCtrlSeq,
|
'\\bibliography': BibliographyCtrlSeq,
|
||||||
'\\bibliographystyle': BibliographyStyleCtrlSeq,
|
'\\bibliographystyle': BibliographyStyleCtrlSeq,
|
||||||
|
'\\maketitle': MaketitleCtrlSeq,
|
||||||
}
|
}
|
||||||
// specializer for control sequences
|
// specializer for control sequences
|
||||||
// return new tokens for specific control sequences
|
// return new tokens for specific control sequences
|
||||||
|
|||||||
+56
-8
@@ -1,6 +1,6 @@
|
|||||||
import { ensureSyntaxTree } from '@codemirror/language'
|
import { ensureSyntaxTree } from '@codemirror/language'
|
||||||
import { EditorState } from '@codemirror/state'
|
import { EditorState } from '@codemirror/state'
|
||||||
import { SyntaxNode, SyntaxNodeRef } from '@lezer/common'
|
import { SyntaxNode, SyntaxNodeRef, Tree } from '@lezer/common'
|
||||||
import { previousSiblingIs } from './common'
|
import { previousSiblingIs } from './common'
|
||||||
import { NodeIntersectsChangeFn, ProjectionItem } from './projection'
|
import { NodeIntersectsChangeFn, ProjectionItem } from './projection'
|
||||||
|
|
||||||
@@ -138,21 +138,69 @@ export const cursorIsAtEndEnvironment = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const findDocumentEnvironment = (state: EditorState): number | null => {
|
const findStartOfDocumentEnvironment = (tree: Tree): number | null => {
|
||||||
const tree = ensureSyntaxTree(state, state.doc.length, HUNDRED_MS)
|
const docEnvironment = findNodeInDocument(tree, 'DocumentEnvironment')
|
||||||
let position: number | null = null
|
return docEnvironment?.getChild('Content')?.from || null
|
||||||
|
}
|
||||||
|
|
||||||
|
const findStartOfAbstractEnvironment = (
|
||||||
|
tree: Tree,
|
||||||
|
state: EditorState
|
||||||
|
): number | null => {
|
||||||
|
const abstractEnvironment = findNodeInDocument(
|
||||||
|
tree,
|
||||||
|
(nodeRef: SyntaxNodeRef) => {
|
||||||
|
return Boolean(
|
||||||
|
nodeRef.type.is('$Environment') &&
|
||||||
|
getEnvironmentName(nodeRef.node, state) === 'abstract'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return abstractEnvironment?.getChild('Content')?.from || null
|
||||||
|
}
|
||||||
|
|
||||||
|
const findMaketitleCommand = (tree: Tree): number | null => {
|
||||||
|
const maketitle = findNodeInDocument(tree, 'Maketitle')
|
||||||
|
return maketitle?.to ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
const findNodeInDocument = (
|
||||||
|
tree: Tree,
|
||||||
|
predicate: number | string | ((node: SyntaxNodeRef) => boolean)
|
||||||
|
): SyntaxNode | null => {
|
||||||
|
let node: SyntaxNode | null = null
|
||||||
|
const predicateFn =
|
||||||
|
typeof predicate !== 'function'
|
||||||
|
? (nodeRef: SyntaxNodeRef) => {
|
||||||
|
return nodeRef.type.is(predicate)
|
||||||
|
}
|
||||||
|
: predicate
|
||||||
tree?.iterate({
|
tree?.iterate({
|
||||||
enter(nodeRef) {
|
enter(nodeRef) {
|
||||||
if (position !== null) {
|
if (node !== null) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (nodeRef.type.is('DocumentEnvironment')) {
|
if (predicateFn(nodeRef)) {
|
||||||
position = nodeRef.node.getChild('Content')?.from || null
|
node = nodeRef.node
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return position
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
export const findStartOfDocumentContent = (
|
||||||
|
state: EditorState
|
||||||
|
): number | null => {
|
||||||
|
const tree = ensureSyntaxTree(state, state.doc.length, HUNDRED_MS)
|
||||||
|
if (!tree) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
findStartOfAbstractEnvironment(tree, state) ??
|
||||||
|
findMaketitleCommand(tree) ??
|
||||||
|
findStartOfDocumentEnvironment(tree)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user