Skip to content

Commit

Permalink
Merge pull request #3599 from Hannah-Sten/input-resolve
Browse files Browse the repository at this point in the history
Make a distinction between commands that can or cannot accept files with any extension
  • Loading branch information
PHPirates authored Jul 12, 2024
2 parents 80da073 + 5816135 commit bd11126
Show file tree
Hide file tree
Showing 19 changed files with 81 additions and 62 deletions.
24 changes: 21 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@

### Fixed

## [0.9.7-alpha.3] - 2024-07-11

### Added

* Improve Evince forward/inverse search support, by Tim Klocke
* Support conversion of arguments in \def -> \newcommand quickfix, by @slideclimb
* Add a simple editor for postfix templates, by @slideclimb
* Add support for \ProvidesExpl(Class|File), by @Sirraide
* Support TeX Live docker image
* Formatter support for plain TeX \if-statements
* Index files from the TEXINPUTS variable, for autocompletion

### Fixed

* Fix Evince synchronization after creating a new run configuration, by Tim Klocke
* Fix unresolved file reference for \input commands

## [0.9.7-alpha.2] - 2024-06-09

### Added
Expand Down Expand Up @@ -376,13 +393,14 @@ Thanks to @jojo2357 and @MisterDeenis for contributing to this release!
* Fix some intention previews. ([#2796](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2796))
* Other small bug fixes and improvements. ([#2776](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2776), [#2774](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2774), [#2765](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2765)-[#2773](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2773))

[Unreleased]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.7-alpha.2...HEAD
[0.9.7-alpha.1]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.6...v0.9.7-alpha.1
[Unreleased]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.7-alpha.3...HEAD
[0.9.7-alpha.3]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.7-alpha.2...v0.9.7-alpha.3
[0.9.7-alpha.2]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.7-alpha.1...v0.9.7-alpha.2
[0.9.7-alpha.1]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.6...v0.9.7-alpha.1
[0.9.6]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.5...v0.9.6
[0.9.5]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.4...v0.9.5
[0.9.4]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.3...v0.9.4
[0.9.3]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.3...v0.9.2
[0.9.3]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.2...v0.9.3
[0.9.2]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.1...v0.9.2
[0.9.1]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.0...v0.9.1
[0.9.0]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.7.33...v0.9.0
Expand Down
1 change: 0 additions & 1 deletion Writerside/topics/Contributing-to-the-source-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ Here we add `\newcommandx` to the `regularStrictCommandDefinitions`, which is th

And here You go: it's done (at least for this simple example)

[//]: # (todo: separate topic?)
## Building from source

We assume that git, IntelliJ, java and LaTeX are installed. If not, follow the normal [installation instructions](Installation-guide.md) first.
Expand Down
26 changes: 13 additions & 13 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ plugins {
id("org.jlleitschuh.gradle.ktlint") version "12.1.1"

// Vulnerability scanning
id("org.owasp.dependencycheck") version "9.2.0"
id("org.owasp.dependencycheck") version "10.0.2"

id("org.jetbrains.changelog") version "2.2.0"
id("org.jetbrains.changelog") version "2.2.1"

id("org.jetbrains.grammarkit") version "2022.3.2.2"
}
Expand Down Expand Up @@ -99,24 +99,24 @@ dependencies {
// Unzipping tar.xz/tar.bz2 files on Windows containing dtx files
implementation("org.codehaus.plexus:plexus-component-api:1.0-alpha-33")
implementation("org.codehaus.plexus:plexus-container-default:2.1.1")
implementation("org.codehaus.plexus:plexus-archiver:4.9.2")
implementation("org.codehaus.plexus:plexus-archiver:4.10.0")

// Parsing json
implementation("com.beust:klaxon:5.6")

// Parsing xml
implementation("com.fasterxml.jackson.core:jackson-core:2.17.1")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.17.1")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.1")
implementation("com.fasterxml.jackson.core:jackson-core:2.17.2")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.17.2")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.2")

// Http requests
implementation("io.ktor:ktor-client-core:2.3.12")
implementation("io.ktor:ktor-client-cio:2.3.11")
implementation("io.ktor:ktor-client-cio:2.3.12")
implementation("io.ktor:ktor-client-auth:2.3.12")
implementation("io.ktor:ktor-client-content-negotiation:2.3.11")
implementation("io.ktor:ktor-server-core:2.3.11")
implementation("io.ktor:ktor-server-jetty:2.3.11")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.11")
implementation("io.ktor:ktor-client-content-negotiation:2.3.12")
implementation("io.ktor:ktor-server-core:2.3.12")
implementation("io.ktor:ktor-server-jetty:2.3.12")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.12")

// Comparing versions
implementation("org.apache.maven:maven-artifact:4.0.0-beta-3")
Expand All @@ -139,11 +139,11 @@ dependencies {
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.10.3")

// Use junit 5 for test cases
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.3")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.2")

// Enable use of the JUnitPlatform Runner within the IDE
testImplementation("org.junit.platform:junit-platform-runner:1.10.2")
testImplementation("org.junit.platform:junit-platform-runner:1.10.3")

testImplementation("io.mockk:mockk:1.13.11")

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pluginVersion = 0.9.7-alpha.2
pluginVersion = 0.9.7-alpha.3

# Info about build ranges: https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html
# Note that an xyz branch corresponds to version 20xy.z and a since build of xyz.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ abstract class LatexPathProviderBase : CompletionProvider<CompletionParameters>(
private var resultSet: CompletionResultSet? = null
private var validExtensions: List<String>? = null
private var absolutePathSupport = true
private var supportsAnyExtension = true

companion object {

Expand All @@ -50,6 +51,7 @@ abstract class LatexPathProviderBase : CompletionProvider<CompletionParameters>(
if (parentCommand is RequiredFileArgument) {
validExtensions = parentCommand.supportedExtensions
absolutePathSupport = parentCommand.isAbsolutePathSupported
supportsAnyExtension = parentCommand.supportsAnyExtension
}

var finalCompleteText = expandCommandsOnce(autocompleteText, project = parameters.originalFile.project, file = parameters.originalFile) ?: autocompleteText
Expand Down Expand Up @@ -171,6 +173,7 @@ abstract class LatexPathProviderBase : CompletionProvider<CompletionParameters>(
* add file to autocompletion dialog
*/
private fun addFileCompletion(baseDir: String, foundFile: VirtualFile) {
// Some commands like \input accept any file extension (supportsExtension), but showing only .tex files is probably a better user experience.
if (validExtensions != null) {
if (validExtensions!!.contains(foundFile.extension).not()) return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import nl.hannahsten.texifyidea.util.files.commandsInFile
import nl.hannahsten.texifyidea.util.files.document
import nl.hannahsten.texifyidea.util.files.findFile
import nl.hannahsten.texifyidea.util.files.findRootFile
import nl.hannahsten.texifyidea.util.replaceString
import nl.hannahsten.texifyidea.util.parser.requiredParameter
import nl.hannahsten.texifyidea.util.replaceString
import java.util.*

/**
Expand All @@ -38,7 +38,7 @@ open class LatexNestedIncludesInspection : TexifyInspectionBase() {
val root = file.findRootFile()

val isInclude = LatexIncludesIndex.Util.getItemsInFileSet(file).any {
it.name == "\\include" && it.requiredParameter(0)?.let { f -> root.findFile(f) } == file
it.name == "\\include" && it.requiredParameter(0)?.let { f -> root.findFile(f, supportsAnyExtension = true) } == file
}

if (!isInclude) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ enum class LatexGenericRegularCommand(
INCLUDEFROM("includefrom", RequiredFolderArgument("absolute path"), RequiredFileArgument("filename", false, false, "tex"), dependency = LatexPackage.IMPORT),
INPUT("input", RequiredFileArgument("sourcefile", true, false, "tex")),
INPUTFROM("inputfrom", RequiredFolderArgument("absolute path"), RequiredFileArgument("filename", false, false, "tex"), dependency = LatexPackage.IMPORT),
INCLUDEGRAPHICS("includegraphics", "key-val-list".asOptional(), RequiredPicturePathArgument("imagefile", isAbsolutePathSupported = true, commaSeparatesArguments = false, FileMagic.graphicFileExtensions), dependency = GRAPHICX),
INCLUDEGRAPHICS("includegraphics", "key-val-list".asOptional(), RequiredPicturePathArgument("imagefile", isAbsolutePathSupported = true, commaSeparatesArguments = false, FileMagic.graphicFileExtensions, supportsAnyExtension = false), dependency = GRAPHICX),
INCLUDEONLY("includeonly", RequiredFileArgument("sourcefile", false, true, "tex")),
INDEXNAME("indexname", "name".asRequired()),
INDEXSPACE("indexspace"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import java.util.regex.Pattern
* @param name
* The name of the required argument.
* @param commaSeparatesArguments True if arguments are separated by commas, for example \command{arg1,arg2}. If false, "arg1,arg2" will be seen as one argument.
* @param supportsAnyExtension True if the command accepts any file extension if provided explicitly.
* @param extensions
* All supported extensions, of which the first extension is the default extension.
* @author Hannah Schellekens
*/
open class RequiredFileArgument(name: String?, open val isAbsolutePathSupported: Boolean = true, open val commaSeparatesArguments: Boolean, vararg extensions: String) : RequiredArgument(name!!, Type.FILE), FileNameMatcher, FileExtensionMatcher {
open class RequiredFileArgument(name: String?, open val isAbsolutePathSupported: Boolean = true, open val commaSeparatesArguments: Boolean, vararg extensions: String, open val supportsAnyExtension: Boolean = true) : RequiredArgument(name!!, Type.FILE), FileNameMatcher, FileExtensionMatcher {

lateinit var supportedExtensions: List<String>
lateinit var defaultExtension: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ package nl.hannahsten.texifyidea.lang.commands
* @author Lukas Heiligenbrunner
*/
// We have to explicitly override isAbsolutePathSupported to avoid a NoSuchMethodError
class RequiredPicturePathArgument(name: String, override val isAbsolutePathSupported: Boolean = true, override val commaSeparatesArguments: Boolean = true, extension: List<String>) : RequiredFileArgument(name, isAbsolutePathSupported, commaSeparatesArguments, *extension.toTypedArray())
class RequiredPicturePathArgument(name: String, override val isAbsolutePathSupported: Boolean = true, override val commaSeparatesArguments: Boolean = true, extension: List<String>, override val supportsAnyExtension: Boolean = true) : RequiredFileArgument(name, isAbsolutePathSupported, commaSeparatesArguments, *extension.toTypedArray(), supportsAnyExtension = supportsAnyExtension)
11 changes: 6 additions & 5 deletions src/nl/hannahsten/texifyidea/reference/InputFileReference.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ import nl.hannahsten.texifyidea.util.magic.CommandMagic
/**
* Reference to a file, based on the command and the range of the filename within the command text.
*
* @param defaultExtension Default extension of the command in which this reference is.
* @param defaultExtension Default extension of the command in which this reference is, in case the argument does not have an extension.
*/
class InputFileReference(
element: LatexCommands,
val range: TextRange,
val extensions: List<String>,
val defaultExtension: String
val defaultExtension: String,
val supportsAnyExtension: Boolean,
) : PsiReferenceBase<LatexCommands>(element) {

init {
Expand Down Expand Up @@ -138,15 +139,15 @@ class InputFileReference(
@Suppress("KotlinConstantConditions")
if (targetFile == null) {
for (rootDirectory in rootDirectories) {
targetFile = rootDirectory.findFile(filePath = processedKey, extensions = extensions)
targetFile = rootDirectory.findFile(filePath = processedKey, extensions, supportsAnyExtension)
if (targetFile != null) break
}
}

// Try content roots
if (targetFile == null && LatexSdkUtil.isMiktexAvailable) {
for (moduleRoot in ProjectRootManager.getInstance(element.project).contentSourceRoots) {
targetFile = moduleRoot.findFile(processedKey, extensions)
targetFile = moduleRoot.findFile(processedKey, extensions, supportsAnyExtension)
if (targetFile != null) break
}
}
Expand All @@ -161,7 +162,7 @@ class InputFileReference(
for (searchPath in searchPaths) {
val path = if (!searchPath.endsWith("/")) "$searchPath/" else searchPath
for (rootDirectory in rootDirectories) {
targetFile = rootDirectory.findFile(path + processedKey, extensions)
targetFile = rootDirectory.findFile(path + processedKey, extensions, supportsAnyExtension)
if (targetFile != null) break
}
if (targetFile != null) break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class BibtexOutputListener(
val logMessage = extractMessage(windowList) ?: return

if (!messageList.contains(logMessage)) {
val file = mainFile?.parent?.findFile(logMessage.fileName ?: mainFile.name)
val file = mainFile?.parent?.findFile(logMessage.fileName ?: mainFile.name, supportsAnyExtension = true)
val messageWithFile = BibtexLogMessage(logMessage.message, logMessage.fileName, logMessage.line, logMessage.type, file)
messageList.add(messageWithFile)
addBibMessageToTree(messageWithFile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ class LatexRunConfiguration(
.flatMap { command -> command.getRequiredParameters() }
.forEach { filename ->
// Find all the files of this chapter, then check if any of the bibliography commands appears in a file in this chapter
val chapterMainFile = psiFile!!.findFile(filename)
val chapterMainFile = psiFile!!.findFile(filename, supportsAnyExtension = true)
?: return@forEach

val chapterFiles = chapterMainFile.referencedFileSet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class LatexOutputListener(
}

private fun findProjectFileRelativeToMain(fileName: String?): VirtualFile? =
mainFile?.parent?.findFile(fileName ?: mainFile.name, listOf("tex"))
mainFile?.parent?.findFile(fileName ?: mainFile.name, listOf("tex"), supportsAnyExtension = true)

/**
* Reset the tree view and the message list when starting a new run. (latexmk)
Expand Down
29 changes: 10 additions & 19 deletions src/nl/hannahsten/texifyidea/util/files/PsiFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import nl.hannahsten.texifyidea.file.BibtexFileType
import nl.hannahsten.texifyidea.file.ClassFileType
import nl.hannahsten.texifyidea.file.LatexFileType
import nl.hannahsten.texifyidea.file.StyleFileType
import nl.hannahsten.texifyidea.index.LatexCommandsIndex
import nl.hannahsten.texifyidea.index.LatexDefinitionIndex
import nl.hannahsten.texifyidea.index.LatexEnvironmentsIndex
import nl.hannahsten.texifyidea.index.LatexIncludesIndex
Expand Down Expand Up @@ -70,7 +69,7 @@ fun PsiFile.isClassFile() = virtualFile?.extension == "cls"
* Looks up the argument that is in the documentclass command, and if the file is found in the project return it.
* Note this explicitly does not find files elsewhere on the system.
*/
fun PsiFile.documentClassFileInProject() = findFile("${documentClass()}.cls")
fun PsiFile.documentClassFileInProject() = findFile("${documentClass()}.cls", supportsAnyExtension = true)

/**
* If the file has a \documentclass command, return the class name, null otherwise.
Expand Down Expand Up @@ -132,20 +131,16 @@ private fun PsiFile.referencedFiles(files: MutableCollection<PsiFile>, rootFile:
/**
* Looks up a file relative to this file.
*
* @param path
* The path relative to this file.
* @param path The path relative to this file.
* @param extensions Search for extensions in this order
* @param supportsAnyExtension If true, the found file is accepted even if the extension is not in the provided non-empty list.
* @return The found file, or `null` when the file could not be found.
*/
fun PsiFile.findFile(path: String, extensions: List<String>? = null): PsiFile? {
fun PsiFile.findFile(path: String, extensions: List<String>? = null, supportsAnyExtension: Boolean): PsiFile? {
if (project.isDisposed) return null
val directory = containingDirectory?.virtualFile

val file = directory?.findFile(
path,
extensions
?: FileMagic.includeExtensions
)
?: return scanRoots(path, extensions)
val file = directory?.findFile(path, extensions ?: FileMagic.includeExtensions, supportsAnyExtension = supportsAnyExtension) ?: return scanRoots(path, extensions)
val psiFile = PsiManager.getInstance(project).findFile(file)
if (psiFile == null || LatexFileType != psiFile.fileType &&
StyleFileType != psiFile.fileType &&
Expand All @@ -170,10 +165,10 @@ fun PsiFile.findIncludedFile(command: LatexCommands): Set<PsiFile> {
return arguments.filter { it.isNotEmpty() }.mapNotNull {
val extension = FileMagic.automaticExtensions[command.name]
if (extension != null) {
findFile(it, listOf(extension))
findFile(it, listOf(extension), supportsAnyExtension = true)
}
else {
findFile(it)
findFile(it, supportsAnyExtension = true)
}
}.toSet()
}
Expand All @@ -188,11 +183,7 @@ fun PsiFile.findIncludedFile(command: LatexCommands): Set<PsiFile> {
fun PsiFile.scanRoots(path: String, extensions: List<String>? = null): PsiFile? {
val rootManager = ProjectRootManager.getInstance(project)
rootManager.contentSourceRoots.forEach { root ->
val file = root.findFile(
path,
extensions
?: FileMagic.includeExtensions
)
val file = root.findFile(path, extensions ?: FileMagic.includeExtensions, supportsAnyExtension = true)
if (file != null) {
return file.psiFile(project)
}
Expand All @@ -210,7 +201,7 @@ fun PsiFile.document(): Document? = PsiDocumentManager.getInstance(project).getD
* @param commandName
* The name of the command including a backslash, or `null` for all commands.
*
* @see [LatexCommandsIndex.Util.getItems]
* see LatexCommandsIndex.Util.getItems
*/
@JvmOverloads
fun PsiFile.commandsInFile(commandName: String? = null): Collection<LatexCommands> {
Expand Down
2 changes: 1 addition & 1 deletion src/nl/hannahsten/texifyidea/util/files/RootFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fun PsiFile.findRootFilesWithoutCache(fileset: Set<PsiFile>): Set<PsiFile> {

if (magicComment.contains(DefaultMagicKeys.ROOT)) {
val path = magicComment.value(DefaultMagicKeys.ROOT) ?: ""
this.findFile(path)?.let { roots.add(it) }
this.findFile(path, supportsAnyExtension = true)?.let { roots.add(it) }
}

if (this.isRoot()) {
Expand Down
Loading

0 comments on commit bd11126

Please sign in to comment.