From 98dcfe1f8333ead9d8286508141a3ef103eddaa2 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sat, 24 Feb 2024 17:55:43 +0100 Subject: [PATCH 1/4] Add argument completion for run config command line --- .../ui/LatexArgumentsCompletionProvider.kt | 26 +++++++++++++++++++ .../run/latex/ui/LatexSettingsEditor.kt | 17 +++++++----- 2 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt diff --git a/src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt new file mode 100644 index 000000000..5d52f424e --- /dev/null +++ b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt @@ -0,0 +1,26 @@ +package nl.hannahsten.texifyidea.run.latex.ui + +import com.intellij.codeInsight.completion.CompletionResultSet +import com.intellij.openapi.externalSystem.service.execution.cmd.CommandLineCompletionProvider +import org.apache.commons.cli.Option +import org.apache.commons.cli.Options + +/** + * Simple way to add autocompletion to a command line editor. + * Based on MavenArgumentsCompletionProvider used in MavenBeforeRunTasksProvider + * Note that there is a similar (and better) solution for fragments, see MavenRunConfigurationSettingsEditor#addCommandLineFragment + */ +class LatexArgumentsCompletionProvider : CommandLineCompletionProvider(options) { + + companion object { + val options = Options().apply { + // option is with one - and .longOpt is with two -- + addOption(Option.builder("etex").longOpt("etex").desc("enable e-TeX extensions").build()) + } + } + + override fun addArgumentVariants(result: CompletionResultSet) { + // Here we can add things to the autocompletion without the - or -- prefix, for example: +// result.addAllElements(listOf("one", "two").map { LookupElementBuilder.create(it) }) + } +} diff --git a/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt index 26b62c146..8fac82663 100644 --- a/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt +++ b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt @@ -3,13 +3,14 @@ package nl.hannahsten.texifyidea.run.latex.ui import com.intellij.execution.configuration.EnvironmentVariablesComponent import com.intellij.openapi.fileChooser.FileChooserDescriptor import com.intellij.openapi.fileChooser.FileTypeDescriptor +import com.intellij.openapi.fileTypes.PlainTextFileType import com.intellij.openapi.options.ConfigurationException import com.intellij.openapi.options.SettingsEditor import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.ui.* import com.intellij.openapi.util.SystemInfo -import com.intellij.ui.RawCommandLineEditor +import com.intellij.ui.EditorTextField import com.intellij.ui.SeparatorComponent import com.intellij.ui.TitledSeparator import com.intellij.ui.components.JBCheckBox @@ -40,7 +41,7 @@ class LatexSettingsEditor(private var project: Project?) : SettingsEditor> private lateinit var enableCompilerPath: JBCheckBox private lateinit var compilerPath: TextFieldWithBrowseButton - private lateinit var compilerArguments: LabeledComponent + private lateinit var compilerArguments: EditorTextField private lateinit var environmentVariables: EnvironmentVariablesComponent private lateinit var mainFile: LabeledComponent> private lateinit var outputPath: LabeledComponent> @@ -91,7 +92,7 @@ class LatexSettingsEditor(private var project: Project?) : SettingsEditor Date: Mon, 26 Feb 2024 08:41:15 +0100 Subject: [PATCH 2/4] Start with parsing compiler help output --- .../run/latex/LatexCommandLineOptionsCache.kt | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt diff --git a/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt b/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt new file mode 100644 index 000000000..e2fb694e2 --- /dev/null +++ b/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt @@ -0,0 +1,91 @@ +package nl.hannahsten.texifyidea.run.latex + +import ai.grazie.utils.dropPrefix +import arrow.atomic.AtomicBoolean +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.progress.ProgressManager +import com.intellij.openapi.progress.Task.Backgroundable +import com.intellij.openapi.project.Project +import nl.hannahsten.texifyidea.run.compiler.LatexCompiler +import nl.hannahsten.texifyidea.util.runCommandWithExitCode + +/** + * Automatically get available command line options for all the LaTeX compilers. + * todo refactor with LatexExternalCommandsIndexCache + */ +object LatexCommandLineOptionsCache { + // Map compiler name to list of (name, description) pairs where name is without the - or -- prefix + val cache = mutableMapOf>>() + + private val isCacheFillInProgress = AtomicBoolean(false) + + /** + * Get the options for the given compiler, or fill the cache if it is empty. + * Cache fill is done in the background because it requires system calls so may take significant time. + */ + fun getOptionsOrFillCache(givenCompiler: String, project: Project): List> { + if (cache.isNotEmpty()) { + return cache[givenCompiler] ?: emptyList() + } + + if (isCacheFillInProgress.compareAndSet(expected = true, new = true)) { + return emptyList() + } + isCacheFillInProgress.getAndSet(true) + + ProgressManager.getInstance().run(object : Backgroundable(project, "Retrieving available command line options for LaTeX compilers...") { + override fun run(indicator: ProgressIndicator) { + try { + for (compiler in LatexCompiler.values()) { + val (output, _) = runCommandWithExitCode(compiler.executableName, "--help") + cache[compiler.executableName] = parseHelpOutput(compiler.executableName, output ?: continue) + } + } + finally { + isCacheFillInProgress.getAndSet(false) + } + } + }) + + return emptyList() + } + + private fun parseHelpOutput(compiler: String, text: String): List>{ + // pdflatex, xelatex have similar (but not the same) format + when (compiler) { + "pdflatex", "xelatex" -> { + return text.split("\n") + // This is the first option, drop everything in front of it + .dropWhile { !it.contains("-cnf-line") } + .flatMap { + val lineParts = it.split(" ") + if (lineParts.size < 2) return@flatMap emptyList() + val option = lineParts.first() + val description = lineParts.drop(1).joinToString(" ") + if (option.startsWith("[-no]")) { + listOf( + Pair(option.dropPrefix("[-no]"), description), + Pair("-no" + option.dropPrefix("[-no]"), description) + ) + } + else if(option.startsWith("-")) { + listOf(Pair(option, description)) + } + else { + emptyList() + } + } + .map { Pair(it.first.trim('-'), it.second) } + } + "lualatex" -> { + return emptyList() + } + "latexmk" -> { + return emptyList() + } + else -> { + return emptyList() + } + } + } +} \ No newline at end of file From f7455a6444d41078f741efa11f1118f7fc7d78dd Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Mon, 26 Feb 2024 21:46:26 +0100 Subject: [PATCH 3/4] Parse --help output for command line arguments --- .../running/run-config-autocomplete.png | Bin 0 -> 22296 bytes .../running/run-config-autocomplete_dark.png | Bin 0 -> 27644 bytes .../topics/Run-configuration-settings.md | 3 + .../run/latex/LatexCommandLineOptionsCache.kt | 102 ++++++++++-------- .../ui/LatexArgumentsCompletionProvider.kt | 10 +- .../run/latex/ui/LatexSettingsEditor.kt | 8 +- .../run/LatexCompilerOptionsParserTest.kt | 81 ++++++++++++++ 7 files changed, 151 insertions(+), 53 deletions(-) create mode 100644 Writerside/images/running/run-config-autocomplete.png create mode 100644 Writerside/images/running/run-config-autocomplete_dark.png create mode 100644 test/nl/hannahsten/texifyidea/run/LatexCompilerOptionsParserTest.kt diff --git a/Writerside/images/running/run-config-autocomplete.png b/Writerside/images/running/run-config-autocomplete.png new file mode 100644 index 0000000000000000000000000000000000000000..5dcce0b592a3f19c50dbdf20be9b6a432441ee81 GIT binary patch literal 22296 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 P5Y}TgJ=IDTo3MWYHSF3R literal 0 HcmV?d00001 diff --git a/Writerside/images/running/run-config-autocomplete_dark.png b/Writerside/images/running/run-config-autocomplete_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..960ad28d3781a27999675dadc6767ca396b5ddc2 GIT binary patch literal 27644 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 literal 0 HcmV?d00001 diff --git a/Writerside/topics/Run-configuration-settings.md b/Writerside/topics/Run-configuration-settings.md index e983db616..027d3b773 100644 --- a/Writerside/topics/Run-configuration-settings.md +++ b/Writerside/topics/Run-configuration-settings.md @@ -111,6 +111,9 @@ Select a path to a LaTeX compiler. Extra arguments to pass to the compiler. It depends on the compiler which ones are there by default. For more info, check the implementation at [https://github.com/Hannah-Sten/TeXiFy-IDEA/blob/master/src/nl/hannahsten/texifyidea/run/compiler/LatexCompiler.kt](https://github.com/Hannah-Sten/TeXiFy-IDEA/blob/master/src/nl/hannahsten/texifyidea/run/compiler/LatexCompiler.kt) +This field has autocompletion, where the available options depend on the compiler that was selected when you opened the dialog. + +![Compiler autocompletion](run-config-autocomplete.png) ## Environment variables diff --git a/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt b/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt index e2fb694e2..c3fe8ae43 100644 --- a/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt +++ b/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt @@ -1,13 +1,15 @@ package nl.hannahsten.texifyidea.run.latex -import ai.grazie.utils.dropPrefix import arrow.atomic.AtomicBoolean import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.Task.Backgroundable import com.intellij.openapi.project.Project import nl.hannahsten.texifyidea.run.compiler.LatexCompiler +import nl.hannahsten.texifyidea.util.remove import nl.hannahsten.texifyidea.util.runCommandWithExitCode +import org.apache.commons.cli.Option +import org.apache.commons.cli.Options /** * Automatically get available command line options for all the LaTeX compilers. @@ -15,7 +17,7 @@ import nl.hannahsten.texifyidea.util.runCommandWithExitCode */ object LatexCommandLineOptionsCache { // Map compiler name to list of (name, description) pairs where name is without the - or -- prefix - val cache = mutableMapOf>>() + val cache = mutableMapOf() private val isCacheFillInProgress = AtomicBoolean(false) @@ -23,22 +25,42 @@ object LatexCommandLineOptionsCache { * Get the options for the given compiler, or fill the cache if it is empty. * Cache fill is done in the background because it requires system calls so may take significant time. */ - fun getOptionsOrFillCache(givenCompiler: String, project: Project): List> { + fun getOptionsOrFillCache(givenCompiler: String, project: Project): Options { if (cache.isNotEmpty()) { - return cache[givenCompiler] ?: emptyList() + return cache[givenCompiler] ?: Options() } if (isCacheFillInProgress.compareAndSet(expected = true, new = true)) { - return emptyList() + return Options() } isCacheFillInProgress.getAndSet(true) + fillCache(project) + return Options() + } + + private fun getOptions(optionsList: List>): Options { + return Options().apply { + for ((option, description) in optionsList) { + // option is with one - and .longOpt is with two --, but both are possible it seems with pdflatex + addOption(Option.builder().longOpt(option).desc(description).build()) + } + } + } + + private fun fillCache(project: Project): List> { ProgressManager.getInstance().run(object : Backgroundable(project, "Retrieving available command line options for LaTeX compilers...") { override fun run(indicator: ProgressIndicator) { try { for (compiler in LatexCompiler.values()) { val (output, _) = runCommandWithExitCode(compiler.executableName, "--help") - cache[compiler.executableName] = parseHelpOutput(compiler.executableName, output ?: continue) + if (output != null) { + val optionsList = parseHelpOutput(compiler.executableName, output) + cache[compiler.executableName] = getOptions(optionsList) + } + else { + cache[compiler.executableName] = Options() + } } } finally { @@ -50,42 +72,38 @@ object LatexCommandLineOptionsCache { return emptyList() } - private fun parseHelpOutput(compiler: String, text: String): List>{ - // pdflatex, xelatex have similar (but not the same) format - when (compiler) { - "pdflatex", "xelatex" -> { - return text.split("\n") - // This is the first option, drop everything in front of it - .dropWhile { !it.contains("-cnf-line") } - .flatMap { - val lineParts = it.split(" ") - if (lineParts.size < 2) return@flatMap emptyList() - val option = lineParts.first() - val description = lineParts.drop(1).joinToString(" ") - if (option.startsWith("[-no]")) { - listOf( - Pair(option.dropPrefix("[-no]"), description), - Pair("-no" + option.dropPrefix("[-no]"), description) - ) - } - else if(option.startsWith("-")) { - listOf(Pair(option, description)) - } - else { - emptyList() - } - } - .map { Pair(it.first.trim('-'), it.second) } - } - "lualatex" -> { - return emptyList() - } - "latexmk" -> { - return emptyList() - } - else -> { - return emptyList() + /** + * Parse the output of pdflatex --help to get available compiler options. + * These are slightly different per compiler. + * Tested with pdflatex, lualatex, xelatex and latexmk + */ + fun parseHelpOutput(compiler: String, text: String): List> { + return text.split("\n") + .asSequence() + .map { it.trim(' ').split(if (compiler == "latexmk") " - " else " ") } + .filter { it.size >= 2 } + .map { Pair(it.first(), it.drop(1).joinToString(" ").trim(' ')) } + .flatMap { (option, description) -> + // [-no] for pdflatex, --[no-] for lualatex + if (option.contains("[-no]") || option.contains("[no-]")) { + val cleanedOption = option.remove("[-no]").remove("[no-]").trim('-') + listOf( + Pair(cleanedOption, description), + Pair("no-$cleanedOption", description) + ) + } + // latexmk + else if (option.contains(" or ")) { + option.split(" or ").map { singleOption -> Pair(singleOption, description) } + } + else if (option.startsWith("-")) { + listOf(Pair(option, description)) + } + else { + emptyList() + } } - } + .map { Pair(it.first.trim(' ').trimStart('-'), it.second) } + .toList() } } \ No newline at end of file diff --git a/src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt index 5d52f424e..3590ea1d2 100644 --- a/src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt +++ b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexArgumentsCompletionProvider.kt @@ -2,7 +2,6 @@ package nl.hannahsten.texifyidea.run.latex.ui import com.intellij.codeInsight.completion.CompletionResultSet import com.intellij.openapi.externalSystem.service.execution.cmd.CommandLineCompletionProvider -import org.apache.commons.cli.Option import org.apache.commons.cli.Options /** @@ -10,14 +9,7 @@ import org.apache.commons.cli.Options * Based on MavenArgumentsCompletionProvider used in MavenBeforeRunTasksProvider * Note that there is a similar (and better) solution for fragments, see MavenRunConfigurationSettingsEditor#addCommandLineFragment */ -class LatexArgumentsCompletionProvider : CommandLineCompletionProvider(options) { - - companion object { - val options = Options().apply { - // option is with one - and .longOpt is with two -- - addOption(Option.builder("etex").longOpt("etex").desc("enable e-TeX extensions").build()) - } - } +class LatexArgumentsCompletionProvider(options: Options) : CommandLineCompletionProvider(options) { override fun addArgumentVariants(result: CompletionResultSet) { // Here we can add things to the autocompletion without the - or -- prefix, for example: diff --git a/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt index 8fac82663..b03e988c1 100644 --- a/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt +++ b/src/nl/hannahsten/texifyidea/run/latex/ui/LatexSettingsEditor.kt @@ -19,6 +19,7 @@ import nl.hannahsten.texifyidea.run.bibtex.BibtexRunConfigurationType import nl.hannahsten.texifyidea.run.compiler.LatexCompiler import nl.hannahsten.texifyidea.run.compiler.LatexCompiler.Format import nl.hannahsten.texifyidea.run.compiler.LatexCompiler.PDFLATEX +import nl.hannahsten.texifyidea.run.latex.LatexCommandLineOptionsCache import nl.hannahsten.texifyidea.run.latex.LatexDistributionType import nl.hannahsten.texifyidea.run.latex.LatexOutputPath import nl.hannahsten.texifyidea.run.latex.LatexRunConfiguration @@ -270,7 +271,11 @@ class LatexSettingsEditor(private var project: Project?) : SettingsEditor + val options = LatexCommandLineOptionsCache.getOptionsOrFillCache(selectedCompiler.executableName, project) + LatexArgumentsCompletionProvider(options).apply(argumentsEditor) + } compilerArguments = argumentsEditor panel.add(compilerArguments) @@ -301,7 +306,6 @@ class LatexSettingsEditor(private var project: Project?) : SettingsEditor Date: Mon, 26 Feb 2024 21:48:26 +0100 Subject: [PATCH 4/4] Remove todo --- .../texifyidea/run/latex/LatexCommandLineOptionsCache.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt b/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt index c3fe8ae43..c994ec478 100644 --- a/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt +++ b/src/nl/hannahsten/texifyidea/run/latex/LatexCommandLineOptionsCache.kt @@ -13,7 +13,6 @@ import org.apache.commons.cli.Options /** * Automatically get available command line options for all the LaTeX compilers. - * todo refactor with LatexExternalCommandsIndexCache */ object LatexCommandLineOptionsCache { // Map compiler name to list of (name, description) pairs where name is without the - or -- prefix