Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as fileSaved from "./file-saved/file-saved"
import { filesDeleted } from "./files-deleted"
import { filesRenamed } from "./files-renamed"
import { MarkdownDefinitionProvider } from "./follow-link/follow-bidi-link"
import { MarkdownCodeActionProvider } from "./rename-title/code-action-provider"
import { MarkdownRenameProvider } from "./rename-title/rename-provider"
import { renameTitle } from "./rename-title/rename-title"
import * as tikibase from "./tikibase"
Expand Down Expand Up @@ -38,6 +39,16 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
// rename document title --> update links with the old document title
context.subscriptions.push(vscode.commands.registerCommand("markdownIDE.renameDocumentTitle", renameTitle))

// rename symbol refactor provider
context.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
"markdown",
new MarkdownCodeActionProvider(),
{ providedCodeActionKinds: MarkdownCodeActionProvider.providedCodeActionKinds }
)
)
context.subscriptions.push(vscode.commands.registerCommand("markdownIDE.renameSymbol", renameTitle))

// register rename provider for built-in VSCode rename symbol functionality
context.subscriptions.push(
vscode.languages.registerRenameProvider("markdown", new MarkdownRenameProvider())
Expand Down
37 changes: 37 additions & 0 deletions src/rename-title/code-action-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as vscode from "vscode"

export class MarkdownCodeActionProvider implements vscode.CodeActionProvider {
public static readonly providedCodeActionKinds = [vscode.CodeActionKind.Refactor]

provideCodeActions(
document: vscode.TextDocument,
range: vscode.Range | vscode.Selection,
context: vscode.CodeActionContext,
token: vscode.CancellationToken
): vscode.ProviderResult<(vscode.CodeAction | vscode.Command)[]> {
if (!this.isFirstHeading(document, range)) {
return []
}

const action = new vscode.CodeAction("Rename heading", vscode.CodeActionKind.Refactor)
action.command = {
command: "markdownIDE.renameSymbol",
title: "Rename heading"
}

return [action]
}

private isFirstHeading(document: vscode.TextDocument, range: vscode.Range): boolean {
const line = document.lineAt(range.start.line)

// Check if we're on the first line and it's a heading
if (range.start.line !== 0) {
return false
}

// Check if the line starts with # (heading marker)
const text = line.text.trim()
return text.startsWith("#") && text.includes(" ")
}
}
66 changes: 65 additions & 1 deletion src/rename-title/rename-provider.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,71 @@
import * as assert from "assert"
import * as vscode from "vscode"

import { MarkdownRenameProvider } from "./rename-provider"
import { MarkdownRenameProvider, MarkdownRenameSymbolProvider } from "./rename-provider"

Check failure on line 4 in src/rename-title/rename-provider.test.ts

View workflow job for this annotation

GitHub Actions / test

'"./rename-provider"' has no exported member named 'MarkdownRenameSymbolProvider'. Did you mean 'MarkdownRenameProvider'?

suite("MarkdownRenameSymbolProvider", () => {
const provider = new MarkdownRenameSymbolProvider()

test("provides refactor action for first heading", async () => {
const document = await vscode.workspace.openTextDocument({
language: "markdown",
content: "# My Heading\n\nSome content here."
})

const range = new vscode.Range(0, 0, 0, 0)
const context: vscode.CodeActionContext = {
diagnostics: [],
triggerKind: vscode.CodeActionTriggerKind.Invoke,
only: undefined
}

const actions = provider.provideCodeActions(document, range, context, {} as vscode.CancellationToken)

assert.ok(Array.isArray(actions))
assert.equal(actions.length, 1)
const action = actions[0] as vscode.CodeAction
assert.equal(action.title, "Rename heading")
assert.equal(action.kind, vscode.CodeActionKind.Refactor)
})

test("does not provide action for non-heading lines", async () => {
const document = await vscode.workspace.openTextDocument({
language: "markdown",
content: "# My Heading\n\nSome content here."
})

const range = new vscode.Range(1, 0, 1, 0) // second line
const context: vscode.CodeActionContext = {
diagnostics: [],
triggerKind: vscode.CodeActionTriggerKind.Invoke,
only: undefined
}

const actions = provider.provideCodeActions(document, range, context, {} as vscode.CancellationToken)

assert.ok(Array.isArray(actions))
assert.equal(actions.length, 0)
})

test("does not provide action for non-first-line headings", async () => {
const document = await vscode.workspace.openTextDocument({
language: "markdown",
content: "# First Heading\n\n## Second Heading"
})

const range = new vscode.Range(2, 0, 2, 0) // third line with second heading
const context: vscode.CodeActionContext = {
diagnostics: [],
triggerKind: vscode.CodeActionTriggerKind.Invoke,
only: undefined
}

const actions = provider.provideCodeActions(document, range, context, {} as vscode.CancellationToken)

assert.ok(Array.isArray(actions))
assert.equal(actions.length, 0)
})
})

suite("MarkdownRenameProvider", () => {
const provider = new MarkdownRenameProvider()
Expand Down
3 changes: 2 additions & 1 deletion src/rename-title/rename-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { eol2string } from "../helpers/eol_to_string"
import * as files from "../helpers/files"
import * as line from "../helpers/line"
import * as links from "../helpers/links"
import { renameTitle } from "./rename-title"

export class MarkdownRenameProvider implements vscode.RenameProvider {
prepareRename(
Expand Down Expand Up @@ -63,7 +64,7 @@ export class MarkdownRenameProvider implements vscode.RenameProvider {
return null
}

// Update the title in the current document
const edit = new vscode.WorkspaceEdit()
const newText = changeMdTitle({
eol: eol2string(document.eol),
newTitle: newName,
Expand Down
Loading