Skip to content
Snippets Groups Projects
Unverified Commit 460246fe authored by James Jianqiao Yu's avatar James Jianqiao Yu Committed by GitHub
Browse files

Merge pull request #4397 from James-Yu/context-aware-latex-format

When formatting a selection of latex, consider the leading spaces
parents 00d64a73 81bf1cac
No related branches found
No related tags found
No related merge requests found
......@@ -29,12 +29,30 @@ class FormattingProvider implements vscode.DocumentFormattingEditProvider, vscod
return undefined
}
public provideDocumentFormattingEdits(document: vscode.TextDocument, _options: vscode.FormattingOptions, _token: vscode.CancellationToken): vscode.ProviderResult<vscode.TextEdit[]> {
return this.formatter?.formatDocument(document) ?? []
public async provideDocumentFormattingEdits(document: vscode.TextDocument, _options: vscode.FormattingOptions, _token: vscode.CancellationToken): Promise<vscode.TextEdit[]> {
const edit = await this.formatter?.formatDocument(document)
if (edit === undefined) {
return []
}
return [ edit ]
}
public provideDocumentRangeFormattingEdits(document: vscode.TextDocument, range: vscode.Range, _options: vscode.FormattingOptions, _token: vscode.CancellationToken): vscode.ProviderResult<vscode.TextEdit[]> {
return this.formatter?.formatDocument(document, range) ?? []
public async provideDocumentRangeFormattingEdits(document: vscode.TextDocument, range: vscode.Range, _options: vscode.FormattingOptions, _token: vscode.CancellationToken): Promise<vscode.TextEdit[]> {
const edit = await this.formatter?.formatDocument(document, range)
if (edit === undefined) {
return []
}
const useSpaces = vscode.window.activeTextEditor?.options.insertSpaces ?? true
const firstLine = document.lineAt(range.start.line)
// Replace all new line characters with new line and spaces, so that
// the indentations are added from the second line.
edit.newText = edit.newText.replaceAll('\n', '\n' + (useSpaces ? ' ' : '\\t').repeat(firstLine.firstNonWhitespaceCharacterIndex))
if (firstLine.firstNonWhitespaceCharacterIndex > range.start.character) {
// \s\s\s|\sf(x)=ax+b
// In this case, the first line need some leading whitespaces.
edit.newText = ' '.repeat(firstLine.firstNonWhitespaceCharacterIndex - range.start.character) + edit.newText
}
return [ edit ]
}
}
......
......@@ -25,7 +25,7 @@ let formatting: boolean = false
lw.onConfigChange('formatting.latexindent.path', () => formatter = '')
async function formatDocument(document: vscode.TextDocument, range?: vscode.Range): Promise<vscode.TextEdit[]> {
async function formatDocument(document: vscode.TextDocument, range?: vscode.Range): Promise<vscode.TextEdit | undefined> {
if (formatting) {
logger.log('Formatting in progress. Aborted.')
}
......@@ -42,7 +42,7 @@ async function formatDocument(document: vscode.TextDocument, range?: vscode.Rang
formatter = ''
logger.log(`Can not find ${formatter} in PATH: ${process.env.PATH}`)
void logger.showErrorMessage('Can not find latexindent in PATH.')
return []
return undefined
}
}
const edit = await format(document, range)
......@@ -113,7 +113,7 @@ function checkPath(): Thenable<boolean> {
})
}
function format(document: vscode.TextDocument, range?: vscode.Range): Thenable<vscode.TextEdit[]> {
function format(document: vscode.TextDocument, range?: vscode.Range): Thenable<vscode.TextEdit | undefined> {
return new Promise((resolve, _reject) => {
const configuration = vscode.workspace.getConfiguration('latex-workshop')
const useDocker = configuration.get('docker.enabled') as boolean
......@@ -165,7 +165,7 @@ function format(document: vscode.TextDocument, range?: vscode.Range): Thenable<v
void logger.showErrorMessage('Formatting failed. Please refer to LaTeX Workshop Output for details.')
logger.log(`Formatting failed: ${err.message}`)
logger.log(`stderr: ${stderrBuffer.join('')}`)
resolve([])
resolve(undefined)
})
worker.on('close', code => {
removeTemporaryFiles()
......@@ -173,16 +173,16 @@ function format(document: vscode.TextDocument, range?: vscode.Range): Thenable<v
void logger.showErrorMessage('Formatting failed. Please refer to LaTeX Workshop Output for details.')
logger.log(`Formatting failed with exit code ${code}`)
logger.log(`stderr: ${stderrBuffer.join('')}`)
return resolve([])
return resolve(undefined)
}
const stdout = stdoutBuffer.join('')
if (stdout !== '') {
const edit = [vscode.TextEdit.replace(range ?? document.validateRange(new vscode.Range(0, 0, Number.MAX_VALUE, Number.MAX_VALUE)), stdout)]
const edit = vscode.TextEdit.replace(range ?? document.validateRange(new vscode.Range(0, 0, Number.MAX_VALUE, Number.MAX_VALUE)), stdout)
logger.log('Formatted ' + document.fileName)
return resolve(edit)
}
return resolve([])
return resolve(undefined)
})
})
}
......@@ -9,7 +9,7 @@ export const texfmt: LaTeXFormatter = {
formatDocument
}
async function formatDocument(document: vscode.TextDocument, range?: vscode.Range): Promise<vscode.TextEdit[]> {
async function formatDocument(document: vscode.TextDocument, range?: vscode.Range): Promise<vscode.TextEdit | undefined> {
const config = vscode.workspace.getConfiguration('latex-workshop')
const program = config.get('formatting.tex-fmt.path') as string
const args = ['--stdin']
......@@ -23,25 +23,25 @@ async function formatDocument(document: vscode.TextDocument, range?: vscode.Rang
stdout += msg
})
const promise = new Promise<vscode.TextEdit[]>(resolve => {
const promise = new Promise<vscode.TextEdit | undefined>(resolve => {
process.on('error', err => {
logger.logError(`Failed to run ${program}`, err)
logger.showErrorMessage(`Failed to run ${program}. See extension log for more information.`)
resolve([])
resolve(undefined)
})
process.on('exit', code => {
if (code !== 0) {
logger.log(`${program} returned ${code} .`)
logger.showErrorMessage(`${program} returned ${code} . Be cautious on the edits.`)
resolve([])
resolve(undefined)
}
// tex-fmt adds an extra newline at the end
if (stdout.endsWith('\n\n')) {
stdout = stdout.slice(0, -1)
}
logger.log(`Formatted using ${program} .`)
resolve([ vscode.TextEdit.replace(range ?? document.validateRange(new vscode.Range(0, 0, Number.MAX_VALUE, Number.MAX_VALUE)), stdout) ])
resolve(vscode.TextEdit.replace(range ?? document.validateRange(new vscode.Range(0, 0, Number.MAX_VALUE, Number.MAX_VALUE)), stdout))
})
})
......
......@@ -124,7 +124,7 @@ export interface LaTeXLinter {
}
export interface LaTeXFormatter {
formatDocument(document: vscode.TextDocument, range?: vscode.Range): Promise<vscode.TextEdit[]>
formatDocument(document: vscode.TextDocument, range?: vscode.Range): Promise<vscode.TextEdit | undefined>
}
export enum TeXElementType { Environment, Macro, Section, SectionAst, SubFile, BibItem, BibField }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment