Skip to content

Commit

Permalink
Support conversion of arguments in \def -> \newcommand quickfix, fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
slideclimb committed Jun 16, 2024
1 parent 56b74c7 commit d3e7a7f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,25 +72,32 @@ open class LatexDiscouragedUseOfDefInspection : TexifyInspectionBase() {
val command = descriptor.psiElement as LatexCommands
val file = command.containingFile
val document = file.document() ?: return
val (cmd, value) = getArguments(command) ?: return
val (cmd, nArgs, value) = getArguments(command) ?: return

val startOFfset = command.textOffset
val endOffset = max(cmd.textOffset + cmd.textLength, value.textOffset + value.textLength)

val numberArgumentsText = nArgs?.let { "[${nArgs}]" } ?: ""
val valueText = if (value.text.startsWith("{") && value.text.endsWith("}")) value.text.drop(1).dropLast(1) else value.text

document.replaceString(startOFfset, endOffset, "$commandName{${cmd.text}}{$valueText}")
document.replaceString(startOFfset, endOffset, "$commandName{${cmd.text}}$numberArgumentsText{$valueText}")
}

open fun getArguments(command: LatexCommands): Pair<PsiElement, PsiElement>? {
open fun getArguments(command: LatexCommands): Triple<PsiElement, Int?, PsiElement>? {
val parent = command.parent
val definedCommand = parent.nextSiblingIgnoreWhitespace()?.firstChildOfType(LatexCommands::class) ?: return null
// Either the definition is wrapped in braces, in which case it will be parsed as a parameter of the command being defined, or it is a sibling of the command
val value = definedCommand.firstChildOfType(LatexParameter::class)
?: definedCommand.nextSiblingIgnoreWhitespace()
?: definedCommand.parent.nextSiblingIgnoreWhitespace()
?: return null
return Pair(definedCommand.commandToken, value)
if (value.text.matches(Regex("""(#\d)+#?"""))) {
val numberOfArguments = Regex("""#\d""").findAll(value.text).count()
val bracedValue = value.nextSiblingIgnoreWhitespace() ?: return null
return Triple(definedCommand.commandToken, numberOfArguments, bracedValue)
} else {
return Triple(definedCommand.commandToken, null, value)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ class LatexDiscouragedUseOfDefInspectionTest : TexifyInspectionTestBase(LatexDis
quickFixName = "Convert to \\newcommand"
)

fun `test quick fix def with argument`() = testNamedQuickFix(
before = """\def\testa#1{#1}""",
after = """\newcommand{\testa}[1]{#1}""",
numberOfFixes = 2,
quickFixName = "Convert to \\newcommand"
)

fun `test quick fix def with multiple arguments`() = testNamedQuickFix(
before = """\def\testa#1#2#3#4{#3#4}""",
after = """\newcommand{\testa}[4]{#3#4}""",
numberOfFixes = 2,
quickFixName = "Convert to \\newcommand"
)

/**
* \newcommand doesn't actually support this, but the inspection is triggered and this seems like the most sensible thing to do.
*/
fun `test quick fix def with argument until next brace`() = testNamedQuickFix(
before = """\def\testa#1#{#1}""",
after = """\newcommand{\testa}[1]{#1}""",
numberOfFixes = 2,
quickFixName = "Convert to \\newcommand"
)

fun `test quick fix def to renewcommand`() = testNamedQuickFix(
before = """\def\a1""",
after = """\renewcommand{\a}{1}""",
Expand Down

0 comments on commit d3e7a7f

Please sign in to comment.