Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intellisense unit test #4422

Merged
merged 10 commits into from
Oct 3, 2024
10 changes: 5 additions & 5 deletions src/compile/recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ export async function build(rootFile: string, langId: string, buildLoop: () => P

// Create output subdirectories for included files
if (tools?.map(tool => tool.command).includes('latexmk') && rootFile === lw.root.subfiles.path && lw.root.file.path) {
createOutputSubFolders(lw.root.file.path)
await createOutputSubFolders(lw.root.file.path)
} else {
createOutputSubFolders(rootFile)
await createOutputSubFolders(rootFile)
}

// Check for invalid toolchain
Expand All @@ -88,14 +88,14 @@ export async function build(rootFile: string, langId: string, buildLoop: () => P
*
* @param {string} rootFile - Path to the root LaTeX file.
*/
function createOutputSubFolders(rootFile: string) {
async function createOutputSubFolders(rootFile: string) {
const rootDir = path.dirname(rootFile)
let outDir = lw.file.getOutDir(rootFile)
if (!path.isAbsolute(outDir)) {
outDir = path.resolve(rootDir, outDir)
}
logger.log(`outDir: ${outDir} .`)
lw.cache.getIncludedTeX(rootFile).forEach(async file => {
for (const file of lw.cache.getIncludedTeX(rootFile)) {
const relativePath = path.dirname(file.replace(rootDir, '.'))
const fullOutDir = path.resolve(outDir, relativePath)
// To avoid issues when fullOutDir is the root dir
Expand All @@ -120,7 +120,7 @@ function createOutputSubFolders(rootFile: string) {
throw(e)
}
}
})
}
}


Expand Down
1 change: 1 addition & 0 deletions src/completion/completer/argument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function from(result: RegExpMatchArray, args: CompletionArgs) {
environment = result[2].match(/{(.*?)}/)?.[1]
}
for (const packageName of Object.keys(packages)) {
lw.completion.usepackage.load(packageName)
if (environment) {
const environments = lw.completion.environment.getEnvFromPkg(packageName, EnvSnippetType.AsMacro) || []
for (const env of environments) {
Expand Down
2 changes: 1 addition & 1 deletion src/completion/completer/citation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ function updateAll(bibFiles?: string[]): CitationItem[] {
async function parseBibFile(fileName: string) {
logger.log(`Parsing .bib entries from ${fileName}`)
const configuration = vscode.workspace.getConfiguration('latex-workshop', vscode.Uri.file(fileName))
if (fs.statSync(fileName).size >= (configuration.get('bibtex.maxFileSize') as number) * 1024 * 1024) {
if ((await lw.external.stat(vscode.Uri.file(fileName))).size >= (configuration.get('bibtex.maxFileSize') as number) * 1024 * 1024) {
logger.log(`Bib file is too large, ignoring it: ${fileName}`)
data.bibEntries.delete(fileName)
return
Expand Down
8 changes: 4 additions & 4 deletions src/completion/completer/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ function provideEnvsAsMacroInPkg(packageName: string, options: string[], suggest
}

// Load environments from the package if not already done
const entry = getEnvFromPkg(packageName, EnvSnippetType.AsMacro)
const envs = getEnvFromPkg(packageName, EnvSnippetType.AsMacro)
// No environment defined in package
if (!entry || entry.length === 0) {
if (!envs || envs.length === 0) {
return
}

const unusual = configuration.get('intellisense.package.unusual') as boolean
// Insert env snippets
for (const env of entry) {
envs.forEach(env => {
if (!useOptionalArgsEntries && env.hasOptionalArgs()) {
return
}
Expand All @@ -172,7 +172,7 @@ function provideEnvsAsMacroInPkg(packageName: string, options: string[], suggest
suggestions.push(env)
defined.add(env.signatureAsString())
}
}
})
}

function parse(cache: FileCache) {
Expand Down
20 changes: 11 additions & 9 deletions src/completion/completer/macro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ function entryCmdToCompletion(item: MacroRaw, packageName?: string, postAction?:
if (! (item.arg.snippet.match(/\$\{?2/) || (item.arg.snippet.match(/\$\{?0/) && item.arg.snippet.match(/\$\{?1/)))) {
item.arg.snippet = item.arg.snippet.replace(/\$1|\$\{1\}/, '$${1:$${TM_SELECTED_TEXT}}').replace(/\$\{1:([^$}]+)\}/, '$${1:$${TM_SELECTED_TEXT:$1}}')
}
// Remove the %keyvals component
item.arg.snippet = item.arg.snippet.replace(/%keyvals/g, '')
suggestion.insertText = new vscode.SnippetString(item.arg.snippet)
} else {
suggestion.insertText = item.name
Expand Down Expand Up @@ -452,26 +454,26 @@ function provideCmdInPkg(packageName: string, options: string[], suggestions: Cm
lw.completion.usepackage.load(packageName)

// No package macro defined
const pkgCmds = data.packageCmds.get(packageName)
if (!pkgCmds || pkgCmds.length === 0) {
const macros = data.packageCmds.get(packageName)
if (!macros || macros.length === 0) {
return
}

const unusual = configuration.get('intellisense.package.unusual') as boolean
// Insert macros
pkgCmds.forEach(cmd => {
if (!useOptionalArgsEntries && cmd.hasOptionalArgs()) {
macros.forEach(mac => {
if (!useOptionalArgsEntries && mac.hasOptionalArgs()) {
return
}
if (!defined.has(cmd.signatureAsString())) {
if (cmd.ifCond && !options.includes(cmd.ifCond)) {
if (!defined.has(mac.signatureAsString())) {
if (mac.ifCond && !options.includes(mac.ifCond)) {
return
}
if (cmd.unusual && !unusual) {
if (mac.unusual && !unusual) {
return
}
suggestions.push(cmd)
defined.add(cmd.signatureAsString())
suggestions.push(mac)
defined.add(mac.signatureAsString())
}
})
}
7 changes: 5 additions & 2 deletions src/completion/latex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,11 @@ export class Provider implements vscode.CompletionItemProvider {
return []
}
let lineToPos = args.line.substring(0, args.position.character)
if (type === 'argument') {
lineToPos = lineToPos.replace(/(?<!\\begin){[^[\]{}]*}/g, '').replace(/\[[^[\]{}]*\]/g, '')
if (type === 'argument' && (lineToPos.includes('\\documentclass') || lineToPos.includes('\\usepackage'))) {
// Remove braced values from documentclass and usepackage
// This is to allow argument regexp to match the following type of lines:
// \documentclass[aspectratio=169,t,fontset=none,xcolor={x11names},|]{ctexbeamer}
lineToPos = lineToPos.replace(/{[^[\]{}]*}/g, '').replace(/\[[^[\]{}]*\]/g, '')
}
const result = lineToPos.match(reg)
let suggestions: vscode.CompletionItem[] = []
Expand Down
20 changes: 10 additions & 10 deletions src/core/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ async function refreshCache(filePath: string, rootPath?: string): Promise<Promis

promises.set(
filePath,
updateAST(fileCache).then(() => {
updateElements(fileCache)
}).finally(() => {
updateAST(fileCache)
.then(() => updateElements(fileCache))
.finally(() => {
lw.lint.label.check()
cachingFilesCount--
promises.delete(filePath)
Expand Down Expand Up @@ -375,7 +375,7 @@ async function updateChildren(fileCache: FileCache, rootPath: string | undefined
async function updateChildrenInput(fileCache: FileCache, rootPath: string) {
const inputFileRegExp = new InputFileRegExp()
while (true) {
const result = inputFileRegExp.exec(fileCache.contentTrimmed, fileCache.filePath, rootPath)
const result = await inputFileRegExp.exec(fileCache.contentTrimmed, fileCache.filePath, rootPath)
if (!result) {
break
}
Expand Down Expand Up @@ -428,7 +428,7 @@ async function updateChildrenXr(fileCache: FileCache, rootPath: string) {
}

const texDirs = vscode.workspace.getConfiguration('latex-workshop').get('latex.texDirs') as string[]
const externalPath = utils.resolveFile([path.dirname(fileCache.filePath), path.dirname(rootPath), ...texDirs], result[2])
const externalPath = await utils.resolveFile([path.dirname(fileCache.filePath), path.dirname(rootPath), ...texDirs], result[2])
if (!externalPath || !await lw.file.exists(externalPath) || path.relative(externalPath, rootPath) === '') {
logger.log(`Failed resolving external ${result[2]} . Tried ${externalPath} ` +
(externalPath && path.relative(externalPath, rootPath) === '' ? ', which is root.' : '.'))
Expand Down Expand Up @@ -462,7 +462,7 @@ async function updateChildrenXr(fileCache: FileCache, rootPath: string) {
* @param {FileCache} fileCache - The cache object containing the file data and
* metadata to be updated.
*/
function updateElements(fileCache: FileCache): void {
async function updateElements(fileCache: FileCache): Promise<void> {
const start = performance.now()
lw.completion.citation.parse(fileCache)
// Package parsing must be before command and environment.
Expand All @@ -473,7 +473,7 @@ function updateElements(fileCache: FileCache): void {
lw.completion.macro.parse(fileCache)
lw.completion.subsuperscript.parse(fileCache)
lw.completion.input.parseGraphicsPath(fileCache)
updateBibfiles(fileCache)
await updateBibfiles(fileCache)
const elapsed = performance.now() - start
logger.log(`Updated elements in ${elapsed.toFixed(2)} ms: ${fileCache.filePath} .`)
}
Expand All @@ -492,15 +492,15 @@ function updateElements(fileCache: FileCache): void {
* @param {FileCache} fileCache - The file cache object to update with
* bibliography files.
*/
function updateBibfiles(fileCache: FileCache) {
async function updateBibfiles(fileCache: FileCache) {
const bibReg = /(?:\\(?:bibliography|addbibresource)(?:\[[^[\]{}]*\])?){(?:\\subfix{)?([\s\S]+?)(?:\})?}|(?:\\putbib)\[(?:\\subfix{)?([\s\S]+?)(?:\})?\]/gm

let result: RegExpExecArray | null
while ((result = bibReg.exec(fileCache.contentTrimmed)) !== null) {
const bibs = (result[1] ? result[1] : result[2]).split(',').map(bib => bib.trim())

for (const bib of bibs) {
const bibPaths = lw.file.getBibPath(bib, path.dirname(fileCache.filePath))
const bibPaths = await lw.file.getBibPath(bib, path.dirname(fileCache.filePath))
for (const bibPath of bibPaths) {
if (isExcluded(bibPath)) {
continue
Expand Down Expand Up @@ -666,7 +666,7 @@ async function parseAuxFile(filePath: string, srcDir: string) {
}
const bibs = (result[1] ? result[1] : result[2]).split(',').map((bib) => { return bib.trim() })
for (const bib of bibs) {
const bibPaths = lw.file.getBibPath(bib, srcDir)
const bibPaths = await lw.file.getBibPath(bib, srcDir)
for (const bibPath of bibPaths) {
if (isExcluded(bibPath)) {
continue
Expand Down
4 changes: 2 additions & 2 deletions src/core/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ function kpsewhich(target: string, isBib: boolean = false): string | undefined {
* @returns {string[]} An array containing the resolved file path(s) for the
* bibliography file, or an empty array if the file could not be resolved.
*/
function getBibPath(bib: string, baseDir: string): string[] {
async function getBibPath(bib: string, baseDir: string): Promise<string[]> {
const configuration = vscode.workspace.getConfiguration('latex-workshop')
const bibDirs = configuration.get('latex.bibDirs') as string[]
let searchDirs: string[] = [baseDir, ...bibDirs]
Expand All @@ -428,7 +428,7 @@ function getBibPath(bib: string, baseDir: string): string[] {
if (lw.root.dir.path) {
searchDirs = [lw.root.dir.path, ...searchDirs]
}
const bibPath = bib.includes('*') ? utils.resolveFileGlob(searchDirs, bib, '.bib') : utils.resolveFile(searchDirs, bib, '.bib')
const bibPath = bib.includes('*') ? utils.resolveFileGlob(searchDirs, bib, '.bib') : await utils.resolveFile(searchDirs, bib, '.bib')

if (bibPath === undefined || bibPath.length === 0) {
if (configuration.get('kpsewhich.bibtex.enabled')) {
Expand Down
8 changes: 4 additions & 4 deletions src/core/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ function findFromRoot(): string | undefined {
*
* @returns {string | undefined} The root file path, or undefined if not found.
*/
function findFromActive(): string | undefined {
async function findFromActive(): Promise<string | undefined> {
if (!vscode.window.activeTextEditor) {
return
}
Expand All @@ -233,7 +233,7 @@ function findFromActive(): string | undefined {
const content = utils.stripCommentsAndVerbatim(vscode.window.activeTextEditor.document.getText())
const result = content.match(getIndicator())
if (result) {
const rootFilePath = findSubfiles(content)
const rootFilePath = await findSubfiles(content)
const activeFilePath = vscode.window.activeTextEditor.document.fileName
if (rootFilePath) {
root.subfiles.path = activeFilePath
Expand All @@ -257,13 +257,13 @@ function findFromActive(): string | undefined {
* @returns {string | undefined} The root file path for subfiles, or undefined
* if not found.
*/
function findSubfiles(content: string): string | undefined {
async function findSubfiles(content: string): Promise<string | undefined> {
const regex = /(?:\\documentclass\[(.*)\]{subfiles})/s
const result = content.match(regex)
if (!result) {
return
}
const filePath = utils.resolveFile([path.dirname(vscode.window.activeTextEditor!.document.fileName)], result[1])
const filePath = await utils.resolveFile([path.dirname(vscode.window.activeTextEditor!.document.fileName)], result[1])
if (filePath) {
logger.log(`Found subfile root ${filePath} from active.`)
}
Expand Down
6 changes: 3 additions & 3 deletions src/language/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { tokenizer } from '../utils/tokenizer'
import * as utils from '../utils/utils'

export class DefinitionProvider implements vscode.DefinitionProvider {
private onAFilename(document: vscode.TextDocument, position: vscode.Position, token: string): string|undefined {
private async onAFilename(document: vscode.TextDocument, position: vscode.Position, token: string): Promise<string | undefined> {
const line = document.lineAt(position.line).text
const escapedToken = utils.escapeRegExp(token)
const regexInput = new RegExp(`\\\\(?:include|input|subfile)\\{${escapedToken}\\}`)
Expand Down Expand Up @@ -40,7 +40,7 @@ export class DefinitionProvider implements vscode.DefinitionProvider {
return
}

provideDefinition(document: vscode.TextDocument, position: vscode.Position): vscode.Location | undefined {
async provideDefinition(document: vscode.TextDocument, position: vscode.Position): Promise<vscode.Location | undefined> {
if (document.uri.scheme !== 'file') {
return
}
Expand Down Expand Up @@ -81,7 +81,7 @@ export class DefinitionProvider implements vscode.DefinitionProvider {
}
}

const filename = this.onAFilename(document, position, token)
const filename = await this.onAFilename(document, position, token)
if (filename) {
return new vscode.Location( vscode.Uri.file(filename), new vscode.Position(0, 0) )
}
Expand Down
14 changes: 7 additions & 7 deletions src/outline/structure/latex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async function constructFile(filePath: string, config: StructureConfig, structs:
return
}
// Get a list of rnw child chunks
const rnwSub = parseRnwChildMacro(content, filePath, lw.root.file.path || '')
const rnwSub = await parseRnwChildMacro(content, filePath, lw.root.file.path || '')

// Parse each base-level node. If the node has contents, that function
// will be called recursively.
Expand Down Expand Up @@ -94,7 +94,7 @@ function chooseCaption(...args: (Ast.Argument | undefined)[]): string {

async function parseNode(
node: Ast.Node,
rnwSub: ReturnType<typeof parseRnwChildMacro>,
rnwSub: Awaited<ReturnType<typeof parseRnwChildMacro>>,
root: { children: TeXElement[] },
filePath: string,
config: StructureConfig,
Expand Down Expand Up @@ -169,7 +169,7 @@ async function parseNode(
}
} else if (node.type === 'macro' && ['input', 'InputIfFileExists', 'include', 'SweaveInput', 'subfile', 'loadglsentries', 'markdownInput'].includes(node.content)) {
const arg0 = argContentToStr(node.args?.[0]?.content || [])
const subFile = resolveFile([ path.dirname(filePath), path.dirname(lw.root.file.path || ''), ...config.texDirs ], arg0)
const subFile = await resolveFile([ path.dirname(filePath), path.dirname(lw.root.file.path || ''), ...config.texDirs ], arg0)
if (subFile) {
element = {
type: TeXElementType.SubFile,
Expand All @@ -184,7 +184,7 @@ async function parseNode(
} else if (node.type === 'macro' && ['import', 'inputfrom', 'includefrom'].includes(node.content)) {
const arg0 = argContentToStr(node.args?.[0]?.content || [])
const arg1 = argContentToStr(node.args?.[1]?.content || [])
const subFile = resolveFile([ arg0, path.join(path.dirname(lw.root.file.path || ''), arg0 )], arg1)
const subFile = await resolveFile([ arg0, path.join(path.dirname(lw.root.file.path || ''), arg0 )], arg1)
if (subFile) {
element = {
type: TeXElementType.SubFile,
Expand All @@ -199,7 +199,7 @@ async function parseNode(
} else if (node.type === 'macro' && ['subimport', 'subinputfrom', 'subincludefrom'].includes(node.content)) {
const arg0 = argContentToStr(node.args?.[0]?.content || [])
const arg1 = argContentToStr(node.args?.[1]?.content || [])
const subFile = resolveFile([ path.dirname(filePath) ], path.join(arg0, arg1))
const subFile = await resolveFile([ path.dirname(filePath) ], path.join(arg0, arg1))
if (subFile) {
element = {
type: TeXElementType.SubFile,
Expand Down Expand Up @@ -382,11 +382,11 @@ function addSectionNumber(struct: TeXElement[], config: StructureConfig, tag?: s
return struct
}

function parseRnwChildMacro(content: string, file: string, rootFile: string): {subFile: string, path: string, line: number}[] {
async function parseRnwChildMacro(content: string, file: string, rootFile: string): Promise<{subFile: string, path: string, line: number}[]> {
const children: {subFile: string, path: string, line: number}[] = []
const childRegExp = new InputFileRegExp()
while(true) {
const result = childRegExp.execChild(content, file, rootFile)
const result = await childRegExp.execChild(content, file, rootFile)
if (!result) {
break
}
Expand Down
Loading
Loading