Skip to content

Commit

Permalink
Handle dragging uri-list into MDX files
Browse files Browse the repository at this point in the history
A mime type of `uri-list` is for example files dragged from the VSCode
tree view.

Images are turnes into Markdown images. These are detected based on a
hardcoded list of file extensions. Other URIs are inserted as-is.

If the dragged URI uses the same scheme as the document it was dragged
in, a relative path is inserted. Otherwise the full URI is used.

Closes #322
  • Loading branch information
remcohaszing committed Oct 30, 2023
1 parent 9075070 commit 271a5b3
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions packages/vscode-mdx/src/document-drop-edit-provider.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
/**
* @typedef {import('mdast').RootContent} RootContent
* @typedef {import('vscode').DocumentDropEditProvider} DocumentDropEditProvider
* @typedef {import('vscode').DataTransferItem} DataTransferItem
*/

import path from 'node:path'
import {Uri, WorkspaceEdit} from 'vscode'
import {toMarkdown} from 'mdast-util-to-markdown'

// https://github.com/microsoft/vscode/blob/1.83.1/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts#L29-L41
const imageExtensions = new Set([
'.bmp',
'.gif',
'.ico',
'.jpe',
'.jpeg',
'.jpg',
'.png',
'.psd',
'.svg',
'.tga',
'.tif',
'.tiff',
'.webp'
])

/**
* @type {DocumentDropEditProvider}
*/
Expand All @@ -14,12 +33,20 @@ export const documentDropEditProvider = {
/** @type {DataTransferItem | undefined} */
let textItem

/** @type {DataTransferItem | undefined} */
let uriListItem

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

if (mime === 'text/uri-list') {
uriListItem = item
continue
}

if (!mime.startsWith('image/')) {
continue
}
Expand All @@ -41,6 +68,33 @@ export const documentDropEditProvider = {
}
}

if (uriListItem) {
const value = await uriListItem.asString()
const uris = value.split(/\r?\n/)
/** @type {string[]} */
const content = []

for (const line of uris) {
const uri = Uri.parse(line)
const value =
uri.scheme === document.uri.scheme
? path.posix.relative(document.uri.path, uri.path)
: line

content.push(
toMarkdown(
imageExtensions.has(path.posix.extname(uri.path))
? {type: 'image', url: value}
: {type: 'text', value}
).trim()
)
}

return {
insertText: content.join(' ')
}
}

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

0 comments on commit 271a5b3

Please sign in to comment.