Automatically rename Markdown files in VS Code using a trigger
Inspired by how Obsidian names Markdown files by title, I put together a small Python script which couples with a VS Code workspace task to achieve the same. Because tasks need to be manually run, a key-binding can be used to quicken the flow.
The assumption is that the file is a Markdown file with the trigger flag in line #2. For example, I always add YAML-type syntax to the top of my blog post drafts, like so:
---
title:
summary:
date:
---
Therefore, my trigger is title:, with a space after the colon.
Any text added to the trigger (after the space) is converted to lowercase, and spaces are replaced with hyphens. The file is renamed, and the original, open file in the editor must be reopened: VS Code shows a line through the old name on the tab title to indicate that the original no longer exists. To put all that more succinctly, the file will be renamed on disc, and needs to be reopened to continue any work in it.
As an example, in a file named draft.md with this title:
---
title: A brand new Blog post
summary:
date:
---
After running the task, the new filename on disc will be: a-brand-new-blog-post.md.
The Python Script
Create a file .vscode/rename-md.py in the workspace with the following content:
#!/usr/bin/env python3
import sys, os
file_path = sys.argv[1]
if not file_path.lower().endswith('.md'): sys.exit()
with open(file_path, 'r', encoding='utf-8') as f: lines = f.readlines()
if len(lines) < 2: sys.exit()
second_line = lines[1].strip()
if not second_line.lower().startswith('title: '): sys.exit()
new_name = second_line[len('title: '):].strip().lower().replace(' ', '-')
if not new_name.endswith('.md'): new_name += '.md'
os.rename(file_path, os.path.join(os.path.dirname(file_path), new_name))
print(f"Renamed file to: {new_name}")
Create a VS Code Task
Create .vscode/tasks.json in the workspace with the following content:
{
"version": "2.0.0",
"tasks": [
{
"label": "Rename Markdown",
"type": "shell",
"command": "python3",
"args": ["${workspaceFolder}/.vscode/rename-md.py", "${file}"],
"problemMatcher": [],
"presentation": { "echo": false, "reveal": "never", "focus": false, "panel": "shared" }
}
]
}
My preference is to never see the terminal window when the task runs, hence the presentation property.
Key-bindings
Add to the global User/keybindings.json to run the task with ctrl+alt+2:
{ "key": "ctrl+alt+2", "command": "workbench.action.tasks.runTask", "args": "Rename Markdown" }
Without a key-binding, this task can be run via the usual ctrl+shift+p –> Run Task –> Rename Markdown.
That’s too many steps…use the key-bindings.
