Skip to content

Commit

Permalink
Support to drag and drop images and text into MDX
Browse files Browse the repository at this point in the history
When dropping an image, the image is downloaded next to the file, and a
markdown link is generated. When text is dropped, the text is inserted
as-is. This only works in VS Code.

This uses a naive text-based approach. This is very similar to the
implementation for markdown files that’s builtin to VS Code.

Closes #322
  • Loading branch information
remcohaszing committed Oct 27, 2023
1 parent d092cdd commit 9d35c41
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/lucky-books-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vscode-mdx': minor
---

Support drag and dropping text and images into the editor.
1 change: 0 additions & 1 deletion fixtures/node16/mixed.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { a } from './a.mdx'
{/*
* Block comments are foldable.
*/}

# Mixed content

Paragraph
Expand Down
52 changes: 52 additions & 0 deletions packages/vscode-mdx/src/document-drop-edit-provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @typedef {import('vscode').DocumentDropEditProvider} DocumentDropEditProvider
* @typedef {import('vscode').DataTransferItem} DataTransferItem
*/

import {Uri, WorkspaceEdit} from 'vscode'

/**
* @type {DocumentDropEditProvider}
*/
export const documentDropEditProvider = {
async provideDocumentDropEdits(document, position, dataTransfer) {
/** @type {DataTransferItem | undefined} */
let textItem

for (const [mime, item] of dataTransfer) {
if (mime === 'text/plain') {
textItem = item
continue
}

if (!mime.startsWith('image/')) {
continue
}

const file = item.asFile()
if (!file) {
continue
}

const additionalEdit = new WorkspaceEdit()
additionalEdit.createFile(Uri.joinPath(document.uri, '..', file.name), {
contents: file,
ignoreIfExists: true
})

return {
insertText: '![](' + file.name + ')',
additionalEdit
}
}

if (textItem) {
const string = await textItem.asString()
return {insertText: string}
}

return {
insertText: ''
}
}
}
10 changes: 9 additions & 1 deletion packages/vscode-mdx/src/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import * as path from 'node:path'
import {DiagnosticModel} from '@volar/language-server'
import * as languageServerProtocol from '@volar/language-server/protocol.js'
import {activateAutoInsertion, supportLabsVersion} from '@volar/vscode'
import {env, workspace} from 'vscode'
import {env, languages, workspace} from 'vscode'
import {LanguageClient} from 'vscode-languageclient/node.js'
import {documentDropEditProvider} from './document-drop-edit-provider.js'

/**
* @type {LanguageClient}
Expand Down Expand Up @@ -43,6 +44,13 @@ export async function activate(context) {

activateAutoInsertion([client], (document) => document.languageId === 'mdx')

context.subscriptions.push(
languages.registerDocumentDropEditProvider(
{language: 'mdx'},
documentDropEditProvider
)
)

return {
volarLabs: {
version: supportLabsVersion,
Expand Down

0 comments on commit 9d35c41

Please sign in to comment.