lean4-htt/tests/server_interactive
Joachim Breitner 06fb4bec52
feat: require indentation in commands, allow empty tactic sequences (#13229)
This PR wraps the top-level command parser with `withPosition` to
enforce indentation in `by` blocks, combined with an empty-by fallback
for better error messages.

This subsumes #3215 (which introduced `withPosition commandParser` but
without the empty-by fallback). It is also related to #9524, which
explores elaboration with empty tactic sequences — this PR reuses that
idea for the empty-by fallback, so that a `by` not followed by an
indented tactic produces an elaboration error (unsolved goals) rather
than a parse error.

**Changes:**
- `topLevelCommandParserFn` now uses `(withPosition commandParser).fn`,
setting the saved position at the start of each top-level command
- `tacticSeqIndentGt` gains an empty tactic sequence fallback
(`pushNone`) so that missing indentation produces an elaboration error
(unsolved goals) instead of a parse error
- `isEmptyBy` in `goalsAt?` removed: with strict `by` indentation, empty
`by` blocks parse successfully via `pushNone` (producing empty nodes)
rather than producing `.missing` syntax, making the `isEmptyBy` check
dead code. The `isEmpty` helper in `isSyntheticTacticCompletion`
continues to work correctly because it handles both `.missing` and empty
nodes from `pushNone` (via the vacuously-true `args.all isEmpty` on
`#[]`)
- Test files updated to indent `by` blocks and expression continuations
that were previously at column 0

**Behavior:**
- Top-level `by` blocks now require indentation (column > 0 for commands
at column 0)
- Commands indented inside `section` require proofs to be indented past
the command's column
- `#guard_msgs in example : True := by` works because tactic indentation
is checked against the outermost command's column
- Expression continuations (not just `by`) must also be indented past
the command, which is slightly more strict but more consistent
- `have : True := by` followed by a dedent now correctly puts `this` in
scope in the outer tactic block (the `have` is structurally complete
with an unsolved-goal error, rather than a parse error)

**Code changes observed in practice (lean4 test suite + Mathlib):**

- `by` blocks: top-level `theorem ... := by` / `decreasing_by` followed
by tactics at column 0 must be indented
- `variable` continuations: `variable {A : Type*} [Foo A]\n{B : Type*}`
where the second line starts at column 0 must be indented (most common
category in Mathlib)
- Expression continuations: `def f : T :=\nexpr` or `#synth Foo\n[args]`
where the body/arguments start at column 0
- Structure literals: `.symm\n{ toFun := ...` where the struct literal
starts at column 0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 14:05:47 +00:00
..
533.lean
533.lean.out.expected
863.lean
863.lean.out.expected
1018unknowMVarIssue.lean
1018unknowMVarIssue.lean.out.expected
1031.lean
1265.lean
1265.lean.out.expected
1403.lean
1403.lean.out.expected
1525.lean
1659.lean
1659.lean.out.expected
2058.lean
2058.lean.out.expected
2881.lean
2881.lean.out.expected
4078.lean
4078.lean.out.expected
4880.lean
4880.lean.out.expected
5659.lean
5659.lean.out.expected
6594.lean
6594.lean.out.expected
10898.lean
10898.lean.out.expected
amb.lean
amb.lean.out.expected
anonHyp.lean
anonHyp.lean.out.expected
autoBoundIssue.lean
autoBoundIssue.lean.out.expected
builtinCodeactions.lean
builtinCodeactions.lean.out.expected
cancellation.lean
cancellation.lean.out.expected
catHover.lean
catHover.lean.out.expected
codeaction.lean
codeaction.lean.out.expected
codeActions.lean
codeActions.lean.out.expected
compHeader.lean
compHeader.lean.out.expected
completion.lean
completion.lean.out.expected
completion2.lean
completion2.lean.out.expected
completion3.lean
completion3.lean.out.expected
completion4.lean
completion4.lean.out.expected
completion5.lean
completion5.lean.out.expected
completion6.lean
completion6.lean.out.expected
completion7.lean
completion7.lean.out.expected
completionAtPrint.lean
completionAtPrint.lean.out.expected
completionBracketedDot.lean
completionBracketedDot.lean.out.expected
completionCheck.lean
completionCheck.lean.out.expected
completionDanglingDot.lean
completionDanglingDot.lean.out.expected
completionDeprecation.lean
completionDeprecation.lean.out.expected
completionEmptyBy.lean test: add empty-by completion tests and column-0 test marker (#13257) 2026-04-02 12:40:38 +00:00
completionEmptyBy.lean.out.expected test: add empty-by completion tests and column-0 test marker (#13257) 2026-04-02 12:40:38 +00:00
completionEndSection.lean
completionEndSection.lean.out.expected
completionEOF.lean
completionEOF.lean.out.expected
completionFallback.lean
completionFallback.lean.out.expected
completionFromExpectedType.lean
completionFromExpectedType.lean.out.expected
completionIStr.lean
completionIStr.lean.out.expected
completionOpenNamespaces.lean
completionOpenNamespaces.lean.out.expected
completionOption.lean
completionOption.lean.out.expected
completionPrefixIssue.lean
completionPrefixIssue.lean.out.expected
completionPrivateTypes.lean
completionPrivateTypes.lean.out.expected
completionPrv.lean
completionPrv.lean.out.expected
completionStructureInstance.lean
completionStructureInstance.lean.out.expected
completionTactics.lean
completionTactics.lean.out.expected
compNamespace.lean
compNamespace.lean.out.expected
definition.lean
definition.lean.out.expected
Diff.lean
Diff.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
discrsIssue.lean
discrsIssue.lean.out.expected
docstringLinksExamples.lean
docstringLinksExamples.lean.out.expected
documentSymbols.lean
documentSymbols.lean.out.expected
dotIdCompletion.lean
dotIdCompletion.lean.out.expected
dottedIdentNotation.lean
dottedIdentNotation.lean.out.expected
editAfterError.lean
editAfterError.lean.out.expected
editCompletion.lean
editCompletion.lean.out.expected
errorExplanationInteractive.lean
errorExplanationInteractive.lean.out.expected
expectedTypeAsGoal.lean
expectedTypeAsGoal.lean.out.expected
explicitAppInstHole.lean
explicitAppInstHole.lean.out.expected
findReferences.lean
findReferences.lean.out.expected
foldingRange.lean
foldingRange.lean.out.expected
fvarIdCollision.lean
fvarIdCollision.lean.out.expected
ghostGoals.lean
ghostGoals.lean.out.expected
goalEOF.lean
goalEOF.lean.out.expected
goalIssue.lean
goalIssue.lean.out.expected
goalsAccomplished.lean
goalsAccomplished.lean.out.expected
goTo.lean
goTo.lean.out.expected
goTo2.lean
goTo2.lean.out.expected
guardMsgsCodeAction.lean
guardMsgsCodeAction.lean.out.expected
haveInfo.lean
haveInfo.lean.out.expected
highlight.lean
highlight.lean.out.expected
highlightMatches.lean
highlightMatches.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
hover.lean
hover.lean.out.expected
hoverAt.lean
hoverAt.lean.out.expected
hoverBinderUnderscore.lean
hoverBinderUnderscore.lean.out.expected
hoverDot.lean
hoverDot.lean.out.expected
hoverException.lean
hoverException.lean.out.expected
hoverMatch.lean
hoverMatch.lean.out.expected
hoverTacticExt.lean
hoverTacticExt.lean.out.expected
importCompletion.lean
importCompletion.lean.out.expected
incomingCallHierarchy.lean
incomingCallHierarchy.lean.out.expected
incomingCallHierarchyWhere.lean
incomingCallHierarchyWhere.lean.out.expected
incrementalCombinator.lean
incrementalCombinator.lean.out.expected
incrementalCommand.lean
incrementalCommand.lean.out.expected
incrementalInduction.lean
incrementalInduction.lean.out.expected
incrementalMutual.lean
incrementalMutual.lean.out.expected
incrementalTactic.lean
incrementalTactic.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
infoIssues.lean
infoIssues.lean.out.expected
inlayHints.lean
inlayHints.lean.out.expected
interactiveDiagnostics.lean
interactiveDiagnostics.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
interactiveGoalGoToLoc.lean
interactiveGoalGoToLoc.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
interactiveGoalPopups.lean
interactiveGoalPopups.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
interactiveTermGoals.lean
interactiveTermGoals.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
interactiveTraces.lean
interactiveTraces.lean.out.expected
internalNamesIssue.lean
internalNamesIssue.lean.out.expected
inWordCompletion.lean
inWordCompletion.lean.out.expected
isRflParallel.lean
issue4527.lean
issue4527.lean.out.expected
issue5021.lean
issue5021.lean.out.expected
issue5597.lean
issue5597.lean.out.expected
jumpMutual.lean
jumpMutual.lean.out.expected
keywordCompletion.lean
keywordCompletion.lean.out.expected
lean3HoverIssue.lean
lean3HoverIssue.lean.out.expected
macroGoalIssue.lean
macroGoalIssue.lean.out.expected
match.lean
match.lean.out.expected
matchPatternHover.lean
matchPatternHover.lean.out.expected
matchStxCompletion.lean
matchStxCompletion.lean.out.expected
moduleHierarchyImports.lean
moduleHierarchyImports.lean.out.expected
outgoingCallHierarchy.lean
outgoingCallHierarchy.lean.out.expected
partialNamespace.lean
partialNamespace.lean.out.expected
plainGoal.lean feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainGoal.lean.out.expected feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainGoalEmptyBy.lean feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainGoalEmptyBy.lean.out.expected feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainTermGoal.lean
plainTermGoal.lean.out.expected
ppShowLetValues.lean
ppShowLetValues.lean.out.expected
rename.lean
rename.lean.out.expected
run_test.lean
run_test.sh chore: check test output before exit code in piles (#12947) 2026-03-17 16:34:21 +00:00
rwElabConst.lean
rwElabConst.lean.out.expected
semanticTokens.lean
semanticTokens.lean.out.expected
semanticTokensVersoDocs.lean
semanticTokensVersoDocs.lean.out.expected
signatureHelp.lean
signatureHelp.lean.out.expected
stdOutput.lean
strInterpSynthError.lean
strInterpSynthError.lean.out.expected
structInstFieldHints.lean
structInstFieldHints.lean.out.expected
structNameParentProj.lean
structNameParentProj.lean.out.expected
tacticInduction.lean
tacticInduction.lean.out.expected
terminationBySuggestion.lean
terminationBySuggestion.lean.out.expected
travellingCompletions.lean
travellingCompletions.lean.out.expected
tryThisCodeAction.lean
tryThisCodeAction.lean.out.expected
unknownIdentifierCodeActions.lean
unknownIdentifierCodeActions.lean.out.expected
unterminatedDocComment.lean
unterminatedDocComment.lean.out.expected
userWidget.lean feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
userWidget.lean.out.expected
workspaceSymbols.lean
workspaceSymbols.lean.out.expected