The usual terminal command for accessing the clipboard on Mac is pbpaste
. However, this doesn't work for image data, so we have to resort to AppleScript:
nnoremap <silent> <buffer> p :call MarkdownClipboardImage()<cr>
function! MarkdownClipboardImage() abort
" Create `img` directory if it doesn't exist
let img_dir = getcwd() . '/img'
if !isdirectory(img_dir)
silent call mkdir(img_dir)
endif
" First find out what filename to use
let index = 1
let file_path = img_dir . "/image" . index . ".png"
while filereadable(file_path)
let index = index + 1
let file_path = img_dir . "/image" . index . ".png"
endwhile
let clip_command = 'osascript'
let clip_command .= ' -e "set png_data to the clipboard as «class PNGf»"'
let clip_command .= ' -e "set referenceNumber to open for access POSIX path of'
let clip_command .= ' (POSIX file \"' . file_path . '\") with write permission"'
let clip_command .= ' -e "write png_data to referenceNumber"'
silent call system(clip_command)
if v:shell_error == 1
normal! p
else
execute "normal! i[](" . file_path . ")"
endif
endfunction
Add the code above to ~/.vim/after/ftplugin/markdown.vim
.
This saves the clipboard data to the file "img/image1.png" if it contains PNG data. It then just uses the :normal!
to insert the desired markdown link.
If the clipboard doesn't contain PNG data (or if we're not in a Markdown file), it performs a regular p command.
If I were using this, I'd tidy it up to support further image types and to leave the cursor in a more helpful position, but this works well as a proof of concept.
(I'd also use a <leader>p
mapping as suggested by Karl Yngve Lervåg — this seems like functionality I'd prefer to invoke specifically — but that's not what you asked for).
Further reading