Skip to content

Commit

Permalink
support meta-comment folding
Browse files Browse the repository at this point in the history
  • Loading branch information
huangyxi authored Oct 7, 2024
1 parent 9e1b5f8 commit e04da9a
Showing 1 changed file with 18 additions and 58 deletions.
76 changes: 18 additions & 58 deletions src/language/folding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as vscode from 'vscode'

export class FoldingProvider implements vscode.FoldingRangeProvider {
private readonly sectionRegex: RegExp[] = []
protected readonly envRegex = /\\(begin){(.*?)}|\\(begingroup)[%\s\\]|\\(end){(.*?)}|\\(endgroup)[%\s\\]|^%\s*#?([rR]egion)|^%\s*#?([eE]ndregion)|^%\s*<\*([|_()\-a-zA-Z0-9]+)>|^%\s*<\/([|_()\-a-zA-Z0-9]+)>|^%\s*\\iffalse\s*(meta-comment)|^%\s*\\(fi)/gm

constructor() {
const sections = vscode.workspace.getConfiguration('latex-workshop').get('view.outline.sections') as string[]
Expand All @@ -20,7 +21,7 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
return sections.map(section => RegExp(`\\\\(?:${section})(?:\\*)?(?:\\[[^\\[\\]\\{\\}]*\\])?{(.*)}`, 'm'))
}

protected getSectionFoldingRanges(document: vscode.TextDocument) {
private getSectionFoldingRanges(document: vscode.TextDocument) {
const startingIndices: number[] = this.sectionRegex.map(_ => -1)
const lines = document.getText().split(/\r?\n/g)
let documentClassLine = -1
Expand Down Expand Up @@ -82,67 +83,13 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
return sections.map(section => new vscode.FoldingRange(section.from, section.to))
}

protected getEnvironmentFoldingRanges(document: vscode.TextDocument) {
private getEnvironmentFoldingRanges(document: vscode.TextDocument) {
const ranges: vscode.FoldingRange[] = []
const opStack: { keyword: string, index: number }[] = []
const text: string = document.getText()
const envRegex: RegExp = /\\(begin){(.*?)}|\\(begingroup)[%\s\\]|\\(end){(.*?)}|\\(endgroup)[%\s\\]|^%\s*#?([rR]egion)|^%\s*#?([eE]ndregion)/gm //to match one 'begin' OR 'end'
while (true) {
const match = envRegex.exec(text)
if (match === null) {
//TODO: if opStack still not empty
return ranges
}
//for 'begin': match[1] contains 'begin', match[2] contains keyword
//for 'end': match[4] contains 'end', match[5] contains keyword
//for 'begingroup': match[3] contains 'begingroup', keyword is 'group'
//for 'endgroup': match[6] contains 'endgroup', keyword is 'group'
//for '% region': match[7] contains 'region', keyword is 'region'
//for '% endregion': match[8] contains 'endregion', keyword is 'region'
let keyword: string = ''
if (match[1]) {
keyword = match[2]
} else if (match[4]) {
keyword = match[5]
} else if (match[3] || match[6]) {
keyword = 'group'
} else if (match[7] || match[8]) {
keyword = 'region'
}

const item = {
keyword,
index: match.index
}
const lastItem = opStack[opStack.length - 1]

if ((match[4] || match[6] || match[8]) && lastItem && lastItem.keyword === item.keyword) { // match 'end' with its 'begin'
opStack.pop()
ranges.push(new vscode.FoldingRange(
document.positionAt(lastItem.index).line,
document.positionAt(item.index).line - 1
))
} else {
opStack.push(item)
}
}
}
}

export class DoctexFoldingProvider extends FoldingProvider {

protected buildSectionRegex(sections: string[]) {
return sections.map(section => RegExp(`%\\s*\\\\(?:${section})(?:\\*)?(?:\\[[^\\[\\]\\{\\}]*\\])?{(.*)}`, 'm'))
}

protected getEnvironmentFoldingRanges(document: vscode.TextDocument) {
const ranges: vscode.FoldingRange[] = []
const opStack: { keyword: string, index: number }[] = []
const text: string = document.getText()
const envRegex: RegExp = /\\(begin){(.*?)}|\\(begingroup)[%\s\\]|\\(end){(.*?)}|\\(endgroup)[%\s\\]|^%\s*#?([rR]egion)|^%\s*#?([eE]ndregion)|^%\s*<\*([|_()\-a-zA-Z0-9]+)>|^%\s*<\/([|_()\-a-zA-Z0-9]+)>/gm

while (true) {
const match = envRegex.exec(text)
const match = this.envRegex.exec(text)
if (match === null) {
//TODO: if opStack still not empty
return ranges
Expand All @@ -153,8 +100,11 @@ export class DoctexFoldingProvider extends FoldingProvider {
//for 'endgroup': match[6] contains 'endgroup', keyword is 'group'
//for '% region': match[7] contains 'region', keyword is 'region'
//for '% endregion': match[8] contains 'endregion', keyword is 'region'
//DocTeX folding support
//for '%<*abc>': match[9] contains '%<*>', keyword is 'abc'
//for '%</abc>': match[10] contains '%</>', keyword is 'abc'
//for '% \iffalse meta-comment': match[11] contains '\iffalse meta-comment', keyword is 'meta-comment'
//for '% \fi': match[12] contains '\fi', keyword is 'meta-comment'
let keyword: string = ''
if (match[1]) {
keyword = match[2]
Expand All @@ -168,6 +118,8 @@ export class DoctexFoldingProvider extends FoldingProvider {
keyword = match[9]
} else if (match[10]) {
keyword = match[10]
} else if (match[11] || match[12]) {
keyword = 'meta-comment'
}

const item = {
Expand All @@ -176,7 +128,7 @@ export class DoctexFoldingProvider extends FoldingProvider {
}
const lastItem = opStack[opStack.length - 1]

if ((match[4] || match[6] || match[8] || match[10]) && lastItem && lastItem.keyword === item.keyword) { // match 'end' with its 'begin'
if ((match[4] || match[6] || match[8] || match[10] || match[12]) && lastItem && lastItem.keyword === item.keyword) { // match 'end' with its 'begin'
opStack.pop()
ranges.push(new vscode.FoldingRange(
document.positionAt(lastItem.index).line,
Expand All @@ -189,6 +141,14 @@ export class DoctexFoldingProvider extends FoldingProvider {
}
}

export class DoctexFoldingProvider extends FoldingProvider {
protected readonly envRegex: RegExp = /\\(begin){(.*?)}|\\(begingroup)[%\s\\]|\\(end){(.*?)}|\\(endgroup)[%\s\\]|^%\s*#?([rR]egion)|^%\s*#?([eE]ndregion)|^%\s*<\*([|_()\-a-zA-Z0-9]+)>|^%\s*<\/([|_()\-a-zA-Z0-9]+)>|^%\s*\\iffalse\s*(meta-comment)|^%\s*\\(fi)/gm

protected buildSectionRegex(sections: string[]) {
return sections.map(section => RegExp(`%\\s*\\\\(?:${section})(?:\\*)?(?:\\[[^\\[\\]\\{\\}]*\\])?{(.*)}`, 'm'))
}
}

export class WeaveFoldingProvider implements vscode.FoldingRangeProvider {
public provideFoldingRanges(
document: vscode.TextDocument,
Expand Down

0 comments on commit e04da9a

Please sign in to comment.