Python Correct Indentation
Fix Python indentation intelligently — with diagnostics, explanations, safe repairs, confidence scoring, preview, and syntax verification.
Python Correct Indentation is an indentation diagnostics and repair system for Visual Studio Code. It does not just re-format your file: it understands Python's block structure, tells you why a line is wrongly indented, proposes the smallest possible fix with a confidence score, shows you a preview, and verifies the result.
Detect → Analyze → Explain → Preview → Correct → Verify
Features
- Structure-aware analysis – a token-aware scanner (strings, triple-quoted strings, brackets, backslash continuations, comments) feeds a block analyzer that simulates the indentation a file should have.
- Diagnostics with three levels of certainty: definite problems (Python would reject them, shown as errors), likely problems (warnings) and suspicious formatting (informational — never an error).
- Plain-language explanations – "
print(user.name) belongs to the if user: block and should be indented one level deeper."
- Quick Fixes / Code Actions – Correct indentation, Correct this line only, Correct surrounding block, Explain indentation problem, tab/space conversion, and a
source.fixAll action.
- Confidence scoring with ranked alternatives for ambiguous code (e.g. Candidate A — 87%, Candidate B — 13%).
- Preview before change – native confirmation dialog plus VS Code's built-in diff editor.
- Python verification – optional
ast.parse check through a local interpreter, with a built-in structural checker as fallback (and for incomplete code).
- Mixed tabs/spaces detection, including Python's own
TabError rule, with convert to spaces / tabs / project setting.
- Project-aware – honours the extension settings,
.editorconfig, pyproject.toml (ruff, yapf, pylint, autopep8 sections), editor.tabSize and editor.insertSpaces; otherwise learns the unit the file already uses and falls back to 4 spaces.
- Smart Paste – optionally re-indents pasted multi-line Python to the cursor, through VS Code's native paste-edit mechanism.
- Indentation health score and a low-key status bar item.
Why Python Correct Indentation?
Most tools either reformat everything or guess silently. Indentation is meaning in Python, so a wrong guess changes behaviour. This extension follows one rule:
Never blindly rewrite code when the intent is uncertain.
| Confidence |
Behaviour |
| High (90–100%) |
Eligible for automatic application after the confirmation step. |
| Medium (70–89%) |
Always previewed. |
| Low (< 70%) and suspicious findings |
Shown as suggestions only — never applied automatically. |
Only leading whitespace is ever modified. Variables, strings, operators, comments, imports and logic are never touched.
How It Works
- Scan – each physical line is classified (statement start, continuation, inside a string, blank, comment) and statements are reduced to blanked code for keyword detection.
- Simulate – the analyzer walks the statements keeping a stack of scopes. For every statement it knows the indentation it has and the indentation it should have. Consistent indentation is learned from the file and left alone.
- Rank – each problem produces one or more repair candidates. The scorer weighs evidence (an unindented first line after a colon is a hard error with one fix; a dedent between two levels is a distance-weighted choice; flattened code is a guess).
- Repair – edits only change leading whitespace; continuation lines and directly attached comments move with their statement, and lines inside multi-line strings are never touched. Repairs are re-analysed between passes so that a skipped guess cannot distort what follows.
- Verify – the result is checked with Python's
ast.parse when available, otherwise with the structural checker.
Installation
- Marketplace: search for Python Correct Indentation (publisher Mythra) in the Extensions view.
- From a VSIX:
code --install-extension python-correct-indentation-1.0.0.vsix
Commands
| Command |
ID |
What it does |
| Python: Correct Indentation |
pythonCorrectIndentation.correct |
Analyze the file, preview and apply corrections. |
| Python: Correct Selected Indentation |
pythonCorrectIndentation.correctSelection |
Same, restricted to the selected lines (analyzed in isolation). |
| Python: Analyze Indentation |
pythonCorrectIndentation.analyze |
Health report in the output panel. |
| Python: Explain Indentation Problem |
pythonCorrectIndentation.explain |
Explains the problem (or why a correct line sits where it does) at the cursor. |
| Python: Normalize Indentation |
pythonCorrectIndentation.normalize |
Convert leading whitespace to spaces, tabs or the project setting; depth is preserved. |
| Python: Verify Indentation |
pythonCorrectIndentation.verify |
Check the file with Python's parser or the built-in checker. |
| Python: Toggle Smart Paste |
pythonCorrectIndentation.toggleSmartPaste |
Turn Smart Paste on or off. |
Keyboard Shortcuts
| Shortcut (Windows/Linux · macOS) |
Command |
Ctrl+Alt+I · Cmd+Alt+I |
Correct Indentation |
Ctrl+Alt+Shift+I · Cmd+Alt+Shift+I |
Correct Selected Indentation |
Both apply only in Python editors. They are deliberately modest; rebind them in Keyboard Shortcuts if they clash with your setup.
Settings
| Setting |
Default |
Description |
pythonCorrectIndentation.enabled |
true |
Diagnostics and code actions. |
pythonCorrectIndentation.indentSize |
0 |
Spaces per level; 0 = automatic. |
pythonCorrectIndentation.useSpaces |
null |
true/false, or null to follow project and editor settings. |
pythonCorrectIndentation.smartPaste |
true |
Indentation-corrected paste. |
pythonCorrectIndentation.smartPastePreview |
false |
Keep normal paste as default; offer the corrected paste in the Paste as… selector. |
pythonCorrectIndentation.smartPasteOnlyObvious |
true |
Smart Paste only applies 90%+ structural fixes. |
pythonCorrectIndentation.previewChanges |
true |
Confirm before applying. Medium-confidence changes are always previewed. |
pythonCorrectIndentation.showDiagnostics |
true |
Show problems in the editor. |
pythonCorrectIndentation.showExplanations |
true |
Include expected indentation/confidence in messages and offer Explain. |
pythonCorrectIndentation.minimumConfidence |
70 |
Repairs below this are suggestions only. |
pythonCorrectIndentation.verifyWithPython |
true |
Use ast.parse when an interpreter is available. |
pythonCorrectIndentation.pythonPath |
"" |
Interpreter for verification. |
pythonCorrectIndentation.showStatusBar |
true |
Status bar item. |
pythonCorrectIndentation.respectProjectConfig |
true |
Read .editorconfig and pyproject.toml. |
pythonCorrectIndentation.diagnosticsDelay |
400 |
Debounce in ms. |
pythonCorrectIndentation.largeFileLineLimit |
50000 |
Automatic analysis is skipped above this size. |
Precedence for the indentation unit: extension setting → .editorconfig → pyproject.toml → editor.tabSize → 4. When the unit comes from the editor or the default, the indentation the file already uses takes priority.
Smart Paste
Smart Paste uses VS Code's document paste edit API. When you paste several lines at the start of a line (or after its indentation), it can:
- re-base the block to the cursor's indentation,
- repair obvious structural problems,
- leave everything else byte-for-byte unchanged.
It never touches pastes made after code on the same line. With smartPastePreview on, plain paste stays the default and Paste with corrected Python indentation appears in the paste widget. Disable it any time with Python: Toggle Smart Paste.
Diagnostics
| Message |
Certainty |
| Expected an indented block after … |
definite (error) |
| Unexpected indentation |
definite (error) |
| Indentation does not match any enclosing block |
definite (error) |
else / elif / except / finally not aligned with its block |
definite or likely |
| Possible missing indentation (flattened code) |
likely (warning) |
| Block has no body |
likely (warning; no repair is invented) |
| Mixed tabs and spaces / TabError |
likely or definite |
| Unusual block indentation |
suspicious (information) |
Confidence-Based Repairs
Each repair shows its evidence: Line 15 — expected 8 spaces — 96% — "Nested inside the current if block." When several readings are plausible you get all of them, ranked and summing to 100%:
Ambiguous indentation detected.
Candidate A — 87% confidence
Candidate B — 13% confidence
Flattened code (all indentation lost) is the hardest case: only the first line after each colon is certain. Following lines are scored from evidence such as how flat the rest of the file is, def/class starts, return/raise and else/except alignment — and are never presented as certain.
Python Verification
When a Python 3 interpreter is found (pythonPath, the interpreter selected in the Python extension, then python3, python, py -3), the corrected text is parsed with ast.parse. The source is sent to the interpreter over stdin and only parsed, never executed. Without Python, the built-in checker validates block structure, bracket balance and string termination, so everything still works offline and on incomplete code.
Examples
# Before # After
if user: if user:
print(user.name) print(user.name)
# Before # After
class Example: class Example:
def method(self): def method(self):
print("hello") print("hello")
# Unexpected indentation # After
for item in items: for item in items:
print(item) print(item)
print("done") print("done")
Supported Python Constructs
if / elif / else, for, while (with else), try / except / else / finally, with, match / case, def, async def / async for / async with, class, decorators, nested functions and classes, one-line compound statements (if x: pass), multi-line statements in () [] {}, backslash continuations, comments, blank lines, strings, triple-quoted strings and f-strings (see limitations).
Configuration
Example .editorconfig:
[*.py]
indent_style = space
indent_size = 4
Example pyproject.toml (ruff, yapf, pylint and autopep8 sections are read on a best-effort basis):
[tool.ruff]
indent-width = 4
Troubleshooting
- No diagnostics: check
pythonCorrectIndentation.enabled/showDiagnostics and that the language mode is Python.
- "No Python 3 interpreter was found": set
pythonCorrectIndentation.pythonPath, or ignore it — the built-in checker is used.
- Wrong indentation unit: set
indentSize, or add an .editorconfig.
- A repair was not applied: it is below
minimumConfidence, or it is a suggestion. Use the Quick Fix menu (Ctrl+.) to apply a specific candidate.
- Undo: applying corrections is one edit — a single Undo reverts it.
The analyzer is linear in file size. Analysis is debounced (400 ms), cached per document version, and skipped above largeFileLineLimit lines. Python is never started while you type; it only runs after a correction and for Verify/Analyze. In development tests the analyzer processed the entire CPython standard library (≈270,000 lines, 500+ files) in under a second.
Privacy
The extension processes code locally and does not send source code to external servers.
There is no telemetry and no network access. The only external process is your local Python interpreter, used for optional syntax verification (source passed over stdin, parsed, never executed).
Requirements
- VS Code 1.97 or newer.
- Optional: Python 3 on the machine for
ast.parse verification.
Known Limitations
- Flattened code is inherently ambiguous; the extension reports confidence rather than certainty and leaves low-confidence changes to you.
- Selections are analyzed in isolation from the rest of the file.
- f-strings with nested quotes of the same kind (Python 3.12) are treated as ordinary strings; this does not affect indentation in practice.
- A tab is measured as one indentation unit; Python's own 8-column rule is used only for the TabError check.
- Python 2 syntax is not supported.
- Soft keywords (
match, case) are recognised heuristically.
- Blocks with no body are reported, never filled in (the extension never adds code).
Contributing
Issues and pull requests are welcome at https://github.com/maryamtahir9/python-correct-indentation. See BUILD.md for setup, tests and debugging.
Issues
Report problems at https://github.com/maryamtahir9/python-correct-indentation/issues.
License
See LICENSE. A license has not been chosen yet — this must be decided before publishing.
Release Notes
1.0.0
First release: structure-aware analysis, diagnostics, quick fixes, confidence scoring, preview, Python/structural verification, mixed tab/space detection, Smart Paste, and project-aware settings. See CHANGELOG.md.