
Fast, predictable Markdown heading-structure tools for Visual Studio Code.
Markdown Heading Tools helps you restructure documents without manually rewriting heading levels, visible heading numbers, or simple tables of contents.
It is intentionally small and focused. It works on Markdown ATX headings, preserves non-heading content, and keeps behavior bounded so document edits stay predictable.
What It Does
- Promote or demote selected Markdown headings.
- Promote or demote the current Markdown section.
- Increase, decrease, normalize, rebuild, or remove visible heading numbering.
- Insert a bounded table of contents from headings below the current cursor line.
Quick Examples
Before:
## Topic
### Detail
After promoting selected headings:
# Topic
## Detail
Increase visible heading numbering
Before:
## 2. Heading
### 2.1 Subheading
After increasing heading numbering:
## 3. Heading
### 3.1 Subheading
Rebuild hierarchical heading numbering
Before:
# Overview
## Scope
## Details
### First Detail
### Second Detail
## Summary
After rebuilding hierarchical heading numbering:
# 1. Overview
## 1.1 Scope
## 1.2 Details
### 1.2.1 First Detail
### 1.2.2 Second Detail
## 1.3 Summary
Remove visible heading numbering
Before:
# 1. Overview
## 1.1 Existing hierarchical number
## 2. Scope
After removing supported heading numbering:
# Overview
## Existing hierarchical number
## Scope
Remove Heading Numbering removes supported visible numbering prefixes, including root prefixes such as 1. and hierarchical prefixes such as 1.1 , and leaves unsupported numbering-like prefixes unchanged.
Insert a table of contents
Before:
Intro text
## First Topic
### Detail
## Second Topic
After running Markdown Heading Tools: Insert Table of Contents with the cursor on Intro text:
- [First Topic](#first-topic)
- [Second Topic](#second-topic)
Intro text
## First Topic
### Detail
## Second Topic
Contents
Why This Extension Exists
Markdown documents often grow by layers: sections move, outlines change, visible heading numbers drift, and tables of contents become stale.
Doing that cleanup by hand is slow and easy to get wrong.
This extension gives you a small set of predictable heading-structure commands:
- change heading depth
- adjust or remove visible numbering
- rebuild hierarchical numbering
- insert a simple table of contents
It is not a general Markdown formatter. It focuses on heading structure.
Features
Change ATX heading levels inside selected text.
## Topic
### Detail
Promoting the selection produces:
# Topic
## Detail
Behavior:
- Heading lines are promoted or demoted.
- Non-heading lines are left unchanged.
- With a selection present, promote/demote keybindings apply only to selected headings.
Change the current section when no text is selected.
Behavior:
- The command finds the section heading under or above the cursor.
- The section heading and nested headings move together.
- Content text remains unchanged.
- Selection-based behavior takes priority when a selection exists.
3) Visible heading-numbering adjustment
Adjust or remove visible heading numbers.
Available numbering operations:
- Increase heading numbering
- Decrease heading numbering
- Normalize heading numbering
- Rebuild hierarchical heading numbering
- Remove heading numbering
Behavior:
- Increase, decrease, normalize, and rebuild commands operate on selected Markdown lines.
- Remove Heading Numbering operates on selected Markdown lines when lines are selected and on the entire file when no lines are selected.
- Non-heading lines are left unchanged.
- Fenced code blocks are ignored.
- Remove Heading Numbering removes supported root and hierarchical visible heading-numbering prefixes and preserves unsupported numbering-like prefixes.
- Numbering commands are available from the Command Palette and editor context menu.
- Numbering commands do not currently have default keyboard shortcuts.
4) Cursor-below table of contents generation
Insert a Markdown bullet-list table of contents from headings below the current cursor line.
Behavior:
- The source region begins immediately after the current cursor line and extends to the end of the document.
- Only the highest-level participating headings are included.
- Heading-like lines inside fenced code blocks are ignored.
- Heading text is preserved in generated links.
- The generated TOC is inserted at the current cursor line if the line is empty.
- The generated TOC is inserted immediately above the current cursor line if the line contains text.
- Selected-block and selection-aware TOC generation are not part of this bounded v1 behavior.
- Nested or multi-level TOC generation is not part of this bounded v1 behavior.
Commands
The extension contributes these commands:
Markdown Heading Tools: Promote Headings in Selection
Markdown Heading Tools: Demote Headings in Selection
Markdown Heading Tools: Promote Current Section
Markdown Heading Tools: Demote Current Section
Markdown Heading Tools: Increase Heading Numbering in Selection
Markdown Heading Tools: Decrease Heading Numbering in Selection
Markdown Heading Tools: Normalize Heading Numbering in Selection
Markdown Heading Tools: Rebuild Hierarchical Heading Numbering in Selection
Markdown Heading Tools: Remove Heading Numbering
Markdown Heading Tools: Insert Table of Contents
Heading-level commands
- Promote Headings in Selection: decreases ATX heading depth in selected lines.
- Demote Headings in Selection: increases ATX heading depth in selected lines.
- Promote Current Section: promotes the current section when no text is selected.
- Demote Current Section: demotes the current section when no text is selected.
Numbering commands
- Increase Heading Numbering in Selection: increases the visible number on the highest-level numbered headings in the selection and propagates changed parent prefixes to descendant headings where applicable.
- Decrease Heading Numbering in Selection: decreases eligible highest-level numbered headings without going below
1 and avoids decreases that would create duplicate top-level numbers.
- Normalize Heading Numbering in Selection: rewrites the highest-level headings in the selection into a sequential visible numbering series and reports when the selection is already normalized.
- Rebuild Hierarchical Heading Numbering in Selection: rebuilds visible hierarchical prefixes across a selected contiguous heading structure and leaves the selection unchanged with an informational message when the selected structure is unsupported.
- Remove Heading Numbering: removes supported root and hierarchical visible heading-numbering prefixes from selected Markdown lines, or from the entire file when no lines are selected.
Table of contents command
- Insert Table of Contents: generates a Markdown bullet-list table of contents from the highest-level headings below the current cursor line, ignoring heading-like lines inside fenced code blocks.
Keybindings
Default keybindings:
Alt + Left → promote heading level
Alt + Right → demote heading level
Behavior:
- No selection: operates on the current section.
- Selection present: operates only on selected headings.
These default keybindings apply only to ATX heading-level promotion/demotion commands.
Heading-numbering, remove-heading-numbering, and table-of-contents commands do not currently have default keyboard shortcuts.
Usage
- Select a block of Markdown text.
- Run
Markdown Heading Tools: Promote Headings in Selection or Markdown Heading Tools: Demote Headings in Selection.
- Or use
Alt + Left / Alt + Right.
- Place the cursor inside a Markdown section.
- Run
Markdown Heading Tools: Promote Current Section or Markdown Heading Tools: Demote Current Section.
- The extension updates the section heading and nested headings together.
Adjust heading numbering in a selection
- Select Markdown lines containing the heading structure.
- Run one of the heading-numbering commands from the Command Palette or editor context menu.
- The extension updates headings in the selected block according to the chosen numbering operation.
Remove heading numbering
- Select Markdown lines to remove supported visible heading numbering from only those lines.
- Or leave no lines selected to operate on the entire file.
- Run
Markdown Heading Tools: Remove Heading Numbering from the Command Palette or editor context menu.
Notes:
- The command removes supported root and hierarchical visible heading-numbering prefixes.
- Unsupported numbering-like prefixes are left unchanged.
- Fenced code blocks are ignored.
- No default keyboard shortcut is assigned to this command.
Insert a table of contents
- Place the cursor on the line where the TOC should be inserted.
- Run
Markdown Heading Tools: Insert Table of Contents from the Command Palette or editor context menu.
- The extension inserts TOC entries for the highest-level headings below the cursor.
Notes:
- If the current line contains text, the TOC is inserted immediately above it.
- If the current line is empty, the TOC is inserted at that line.
- If no headings exist below the cursor, the document is left unchanged and an informational message is shown.
- No default keyboard shortcut is assigned to this command.
Behavior Boundaries
This extension is intentionally bounded.
The extension works on Markdown ATX headings:
# Heading
## Heading
### Heading
Setext headings are not part of the current command surface.
Fenced code blocks
Heading-like lines inside fenced code blocks are ignored by heading-numbering and table-of-contents behavior.
Example:
```md
# This is code, not a document heading
```
# This is a document heading
Remove heading numbering scope
Remove Heading Numbering removes supported root and hierarchical visible heading-numbering prefixes from ATX headings.
Examples of supported prefixes:
# 1. Heading
## 12. Heading
## 1.1 Heading
### 1.2.3 Heading
Examples of unsupported numbering-like prefixes that are left unchanged:
# 1 Heading
# 01. Heading
# 1) Heading
# 1.2. Heading
# 1.01 Heading
# A. Heading
If one or more lines are selected, the command operates only on selected lines.
If no lines are selected, the command operates on the entire file.
Table of contents scope
The TOC command is cursor-below only.
It does not currently generate a TOC from:
- an arbitrary selected block
- headings above the cursor
- nested/multi-level heading structures
This extension does not attempt to format general Markdown prose, lists, tables, links, or whitespace.
It focuses on heading structure.
Installation
Install from VSIX
- Download the
.vsix file from the release.
- Open Extensions in VS Code.
- Click the
... menu.
- Select Install from VSIX....
- Choose the downloaded file.
Local development install
Open the project in VS Code and press F5 to launch an Extension Development Host.
Development
Install dependencies:
npm install
Run tests:
npm test
Run the extension in development mode:
F5
Packaging
Package the extension as a VSIX:
npx vsce package
Inspect packaged files:
npx vsce ls --tree
The release package should contain only the extension runtime and release-facing files.
Release Approach
This project uses tagged releases. See CHANGELOG.md for released changes.
Versioning
This project follows Semantic Versioning. See VERSIONING.md.
Changelog
See CHANGELOG.md.
Contributing
See CONTRIBUTING.md.
Security
See SECURITY.md.
License
MIT. See LICENSE.