Compare commits

...

2 Commits

Author SHA1 Message Date
Joachim Breitner
f85a6f3631 refactor: revert completion assertion mode, use plain completion directives
Remove the completion assertion mode (has/is empty) from the test runner
and use plain `completion` directives in the empty-by tests instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 12:27:16 +00:00
Joachim Breitner
87fb4d6a7c test: add completion tests for empty by blocks
Add `--⬑` test marker variant that targets the column of `--` itself
(enabling column 0 tests, which `--^` cannot reach).

Add completion assertion mode: `--^ completion: has "skip"` checks that
a completion item with the given label exists, and `--^ completion: is empty`
checks that no completions are returned. This avoids logging the full
completion JSON, making tests stable against docstring changes.

Test tactic completion in empty `by` blocks for both top-level `by`
and nested `by` (inside `id <| have := by`). For each, test completion
at various column positions on the line below `by`: indented past `by`,
at column 2, and at column 0.

All positions currently offer tactic completions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 12:01:20 +00:00
3 changed files with 1145 additions and 4 deletions

View File

@@ -641,13 +641,13 @@ def processGenericRequest : RunnerM Unit := do
let params := params.setObjVal! "position" (toJson s.pos)
logResponse s.method params
def processDirective (ws directive : String) (directiveTargetLineNo : Nat) : RunnerM Unit := do
def processDirective (_ws directive : String) (directiveTargetLineNo : Nat)
(directiveTargetColumn : Nat) : RunnerM Unit := do
let directive := directive.drop 1
let colon := directive.find ':'
let method := directive.sliceTo colon |>.trimAscii |>.copy
-- TODO: correctly compute in presence of Unicode
let directiveTargetColumn := ws.rawEndPos + "--"
let pos : Lsp.Position := { line := directiveTargetLineNo, character := directiveTargetColumn.byteIdx }
let pos : Lsp.Position := { line := directiveTargetLineNo, character := directiveTargetColumn }
let params :=
if h : ¬colon.IsAtEnd then
directive.sliceFrom (colon.next h) |>.trimAscii.copy
@@ -686,10 +686,15 @@ def processLine (line : String) : RunnerM Unit := do
match directive.front with
| 'v' => pure <| ( get).lineNo + 1 -- TODO: support subsequent 'v'... or not
| '^' => pure <| ( get).lastActualLineNo
-- `⬑` is like `^` but targets the column of the `--` marker itself (i.e. column 0 when the
-- marker is at the start of the line), rather than the column after `--`.
| '' => pure <| ( get).lastActualLineNo
| _ =>
skipLineWithoutDirective
return
processDirective ws directive directiveTargetLineNo
let directiveTargetColumn :=
if directive.front == '' then ws.rawEndPos.byteIdx else (ws.rawEndPos + "--").byteIdx
processDirective ws directive directiveTargetLineNo (directiveTargetColumn := directiveTargetColumn)
skipLineWithDirective

View File

@@ -0,0 +1,122 @@
prelude
import Init.Notation
/-
Tests for tactic completion in empty `by` blocks (no indented tactics follow).
Tests cover:
- Top-level `by`
- Nested `by` inside expressions (e.g. `id <| have := by`)
- Completion at various columns on the line below `by`
Note: `--^` tests at the column of `^`; `--⬑` tests at the column of `--` itself (for column 0).
To test a column on the line below `by`, we place an indented comment there so that the tested
column falls within the leading whitespace (matching how completionTactics.lean works).
-/
/-- A docstring -/
syntax (name := skip) "skip" : tactic
-- ===== On the `by` token itself (no completions expected) =====
-- column 20 on `by` line (end of `by` token, before whitespace)
example : True := by
--^ completion
-- column 20 on nested `by` line (end of `by` token, before whitespace)
example : True := id <|
have : True := by
--^ completion
-- ===== Top-level `by`, non-indented content following =====
-- column 21 on line below `by`
example : True := by
-- below by
--^ completion
sorry
-- column 0 on line below `by`
example : True := by
-- below by
--⬑ completion
sorry
-- column 2 on line below `by`
example : True := by
-- below by
--^ completion
sorry
-- ===== Top-level `by`, no tactics following =====
-- column 21 on line below `by`
example : True := by
-- below by
--^ completion
-- column 0 on line below `by`
example : True := by
-- below by
--⬑ completion
-- column 2 on line below `by`
example : True := by
-- below by
--^ completion
-- ===== Nested `by`, content following =====
-- column 21 on line below `by`
example : True := id <|
have : True := by
-- below by
--^ completion
sorry
-- column 2 on line below `by` (at column of `have` line)
example : True := id <|
have : True := by
-- below by
--^ completion
sorry
-- column 0 on line below `by`
example : True := id <|
have : True := by
-- below by
--⬑ completion
sorry
-- column 4 on line below `by` (indented past `have` but not past `by`)
example : True := id <|
have : True := by
-- below by
--^ completion
sorry
-- ===== Nested `by`, no tactics following =====
-- column 21 on line below `by`
example : True := id <|
have : True := by
-- below by
--^ completion
-- column 2 on line below `by` (at column of `have` line)
example : True := id <|
have : True := by
-- below by
--^ completion
-- column 0 on line below `by`
example : True := id <|
have : True := by
-- below by
--⬑ completion
-- column 4 on line below `by`
example : True := id <|
have : True := by
-- below by
--^ completion

File diff suppressed because it is too large Load Diff