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

Fix timeout when running system commands #1681

Merged
merged 10 commits into from
Dec 7, 2020
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ plugins {
}

group = "nl.hannahsten"
version = "0.7.2-alpha.5"
version = "0.7.2-alpha.6"

repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package nl.hannahsten.texifyidea.inspections.latex
import com.intellij.psi.PsiElement
import nl.hannahsten.texifyidea.inspections.TexifyRegexInspection
import nl.hannahsten.texifyidea.psi.LatexCommands
import nl.hannahsten.texifyidea.util.Magic
import nl.hannahsten.texifyidea.util.isCommandDefinition
import nl.hannahsten.texifyidea.util.parentOfType
import nl.hannahsten.texifyidea.util.parentsOfType
import java.util.regex.Pattern

Expand All @@ -16,6 +18,6 @@ class LatexEscapeHashOutsideCommandInspection : TexifyRegexInspection(
replacement = { _, _ -> """\#""" }
) {
override fun checkContext(element: PsiElement): Boolean {
return super.checkContext(element) && element.parentsOfType<LatexCommands>().all { !it.isCommandDefinition() }
return super.checkContext(element) && element.parentsOfType<LatexCommands>().all { !it.isCommandDefinition() } && element.parentOfType(LatexCommands::class)?.name !in Magic.Command.urls
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ import com.intellij.refactoring.suggested.createSmartPointer
import nl.hannahsten.texifyidea.insight.InsightGroup
import nl.hannahsten.texifyidea.inspections.TexifyInspectionBase
import nl.hannahsten.texifyidea.intentions.LatexAddLabelIntention
import nl.hannahsten.texifyidea.lang.LatexDocumentClass
import nl.hannahsten.texifyidea.lang.magic.MagicCommentScope
import nl.hannahsten.texifyidea.psi.LatexCommands
import nl.hannahsten.texifyidea.psi.LatexEnvironment
import nl.hannahsten.texifyidea.psi.LatexPsiHelper
import nl.hannahsten.texifyidea.settings.TexifyConfigurable
import nl.hannahsten.texifyidea.settings.TexifySettings
import nl.hannahsten.texifyidea.util.*
import nl.hannahsten.texifyidea.util.files.commandsInFile
import nl.hannahsten.texifyidea.util.files.environmentsInFile
import nl.hannahsten.texifyidea.util.files.openedEditor
import nl.hannahsten.texifyidea.util.files.*
import org.jetbrains.annotations.Nls
import java.util.*

Expand All @@ -46,7 +45,13 @@ open class LatexMissingLabelInspection : TexifyInspectionBase() {
val minimumLevel = Magic.Command.labeledLevels[TexifySettings.getInstance().missingLabelMinimumLevel] ?: error("No valid minimum level given")
val labeledCommands = Magic.Command.labeledLevels.keys.filter { command ->
Magic.Command.labeledLevels[command]?.let { it <= minimumLevel } == true // -1 is a higher level than 0
}.map { "\\" + it.command }
}.map { "\\" + it.command }.toMutableList()

// Document classes like book and report provide \part as sectioning, but with exam class it's a part in a question
if (file.findRootFile().documentClass() == LatexDocumentClass.EXAM.name) {
labeledCommands.remove("\\part")
}

file.commandsInFile().filter {
labeledCommands.contains(it.name) && it.name != "\\item" && !it.hasStar()
}.forEach { addCommandDescriptor(it, descriptors, manager, isOntheFly) }
Expand Down
32 changes: 32 additions & 0 deletions src/nl/hannahsten/texifyidea/lang/LatexDocumentClass.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package nl.hannahsten.texifyidea.lang

/**
* All LaTeX document classes for which TeXiFy has special behaviour.
*
* @author Thomas
*/
open class LatexDocumentClass(
val name: String,
vararg val parameters: String = emptyArray()
) {

companion object {
val EXAM = LatexDocumentClass("exam")
}

override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other !is LatexDocumentClass) {
return false
}

val aPackage = other as LatexDocumentClass?
return name == aPackage!!.name
}

override fun hashCode() = name.hashCode()

override fun toString() = "DocumentClass{$name}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ open class LatexCommandLineState(environment: ExecutionEnvironment, private val
}

firstRunSetup(compiler)
runConfig.outputPath.updateOutputSubDirs()
if (!runConfig.getLatexDistributionType().isMiktex()) {
runConfig.outputPath.updateOutputSubDirs()
}

val handler = createHandler(mainFile, compiler)
val isMakeindexNeeded = runMakeindexIfNeeded(handler, mainFile, runConfig.filesToCleanUp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import nl.hannahsten.texifyidea.run.latex.logtab.LatexLogMagicRegex.lineNumber
import nl.hannahsten.texifyidea.util.containsAny
import nl.hannahsten.texifyidea.util.firstIndexOfAny
import nl.hannahsten.texifyidea.util.remove
import java.util.ArrayDeque
import java.util.*

class LatexFileStack(
vararg val file: String,
Expand Down Expand Up @@ -116,10 +116,9 @@ class LatexFileStack(
if (notClosedNonFileOpenParentheses > 0) notClosedNonFileOpenParentheses--
else {
if (debug) logger.info("$line ---- Closing ${peek()}")
if (isEmpty()) {
throw TeXception("Extra closing parenthesis: could not close a file which was not opened. Please report the log output to the issue tracker. Line content: $line")
if (!isEmpty()) {
pop()
}
pop()
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/nl/hannahsten/texifyidea/util/Magic.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import nl.hannahsten.texifyidea.TexifyIcons
import nl.hannahsten.texifyidea.file.*
import nl.hannahsten.texifyidea.inspections.latex.LatexLineBreakInspection
import nl.hannahsten.texifyidea.lang.CommandManager
import nl.hannahsten.texifyidea.lang.LatexRegularCommand.*
import nl.hannahsten.texifyidea.lang.LatexPackage
import nl.hannahsten.texifyidea.lang.LatexPackage.Companion.ALGORITHM2E
import nl.hannahsten.texifyidea.lang.LatexPackage.Companion.ALGPSEUDOCODE
Expand All @@ -22,6 +21,7 @@ import nl.hannahsten.texifyidea.lang.LatexPackage.Companion.MATHTOOLS
import nl.hannahsten.texifyidea.lang.LatexPackage.Companion.NATBIB
import nl.hannahsten.texifyidea.lang.LatexPackage.Companion.PDFCOMMENT
import nl.hannahsten.texifyidea.lang.LatexPackage.Companion.XCOLOR
import nl.hannahsten.texifyidea.lang.LatexRegularCommand.*
import org.intellij.lang.annotations.Language
import java.awt.Color
import java.util.regex.Pattern
Expand Down Expand Up @@ -634,7 +634,7 @@ object Magic {
* All LaTeX commands that contain a url (in their first parameter).
*/
@JvmField
val urls = hashSetOf("\\url", "\\href")
val urls = hashSetOf("\\" + URL.command, "\\" + HREF.command)

/**
* All BibTeX tags that take a url as their parameter.
Expand Down
11 changes: 8 additions & 3 deletions src/nl/hannahsten/texifyidea/util/SystemEnvironment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,14 @@ fun runCommand(vararg commands: String): String? {
.redirectError(ProcessBuilder.Redirect.PIPE)
.start()

// Timeout value
proc.waitFor(3, TimeUnit.SECONDS)
proc.inputStream.bufferedReader().readText().trim() + proc.errorStream.bufferedReader().readText().trim()
if (proc.waitFor(3, TimeUnit.SECONDS)) {
proc.inputStream.bufferedReader().readText().trim() + proc.errorStream.bufferedReader().readText().trim()
}
else {
proc.destroy()
proc.waitFor()
null
}
}
catch (e: IOException) {
null // Don't print the stacktrace because that is confusing.
Expand Down
14 changes: 9 additions & 5 deletions src/nl/hannahsten/texifyidea/util/files/PsiFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,16 @@ 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(): PsiFile? {
val command = commandsInFile().asSequence()
fun PsiFile.documentClassFileInProject() = findFile("${documentClass()}.cls")

/**
* If the file has a \documentclass command, return the class name, null otherwise.
*/
fun PsiFile.documentClass(): String? {
return commandsInFile().asSequence()
.filter { it.name == "\\documentclass" }
.firstOrNull() ?: return null
val argument = command.requiredParameter(0) ?: return null
return findFile("$argument.cls")
.firstOrNull()
?.requiredParameter(0)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class LatexAvoidEqnarrayInspectionTest : TexifyInspectionTestBase(LatexAvoidEqna
\end{eqnarray}
""".trimIndent())

fun `test eqnarray* warning`() = testHighlighting("""
fun `test eqnarray star warning`() = testHighlighting("""
\begin{<warning descr="Avoid using the 'eqnarray*' environment">eqnarray*</warning>}
x
\end{eqnarray*}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ class LatexMissingLabelInspectionTest : TexifyInspectionTestBase(LatexMissingLab
""".trimIndent()
)

fun `test exam parts`() = testHighlighting(
"""
\documentclass{exam}
\begin{document}
\begin{questions}
\question
\begin{parts}
\part a
\end{parts}
\end{questions}
\end{document}
""".trimIndent()
)

fun `test quick fix in listings with no other parameters`() = testQuickFix(
before = """
\begin{document}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,11 @@ class LatexUnresolvedReferenceInspectionTest : TexifyInspectionTestBase(LatexUnr
myFixture.checkHighlighting()
}

// Test randomly fails
// fun testBibtexReference() {
// myFixture.configureByFile("references.bib")
// // Force indexing
// myFixture.checkHighlighting()
// val name = getTestName(false) + ".tex"
// // For some reason we need to copy the .bib again
// myFixture.configureByFiles(name, "references.bib")
// myFixture.checkHighlighting()
// }
fun testBibtexReference() {
val name = getTestName(false) + ".tex"
myFixture.configureByFiles(name, "references.bib")
myFixture.checkHighlighting()
}

fun testFigureReferencedCustomCommandOptionalParameter() {
myFixture.configureByText(
Expand Down Expand Up @@ -99,4 +94,9 @@ class LatexUnresolvedReferenceInspectionTest : TexifyInspectionTestBase(LatexUnr
myFixture.configureByText(LatexFileType, """\input{name,with,.tex}""")
myFixture.checkHighlighting()
}

fun testNewcommand() {
myFixture.configureByText(LatexFileType, """\newcommand{\bla}[1]{\includegraphics{#1}}""")
myFixture.checkHighlighting()
}
}