Markdownの編集時にクリップボードの画像へのリンクを貼り付け


9

クリップボードに画像があり、テキストとしてドキュメントに貼り付けたい[](img/image1.png)

最初にそれをそのディレクトリにコピーする代わりにp、Vimで1回キーを押すだけでそれを実行したいと思います。したがって、フックしてp、Markdownファイルを編集しているかどうかを確認し、画像をクリップボードからその場所img/image1.png[](img/image1.png)保存して、ファイルに挿入します。

これはVimで可能ですか?

私はmacOSとターミナルVimを使用しています。


わかりやすくするために、これは「まるで単語のように直接イメージをコピーしました」ですか、「ファインダーでイメージファイルをコピーしました」ですか。(実際にそれらが異なるかどうかはわかりません...)
Joe

回答:


2

Macでクリップボードにアクセスするための通常の端末コマンドはpbpasteです。ただし、これは画像データでは機能しないため、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

上記のコードをに追加します~/.vim/after/ftplugin/markdown.vim

これにより、PNGデータが含まれている場合、クリップボードデータがファイル「img / image1.png」に保存されます。次に、を使用し:normal!て目的のマークダウンリンクを挿入します。

クリップボードにPNGデータが含まれていない場合(またはMarkdownファイルに含まれていない場合)、通常のpコマンドが実行されます。

これを使用している場合は、さらに画像タイプをサポートし、カーソルをより役立つ位置に残すために整頓しておきますが、これは概念実証としてうまく機能します。

(私はKarl YngveLervågによって提案され<leader>pマッピングも使用します —これは私が特に呼び出したい機能のように見えます—しかし、それはあなたが要求したものではありません)。

参考文献


いいですね、あなたのソリューションが実際にMacOSの要件に答えているので、あなたへのリンクで私の答えを更新しました。
Karl YngveLervåg2017年

1
@KarlYngveLervågありがとう、それはあなたにとても親切です。それがあなたのものでなければ、私も答えを書いていないでしょう。あなたはネイティブのMacソリューションを見つけるように私を奮い立たせました!
リッチ

3

次のソリューションは、ほとんどのLinuxシステムで機能するはずです。比較的更新されたxclipツールが必要です。MacOS / OSXで動作するソリューションについては、@ Richの回答を参照してください。


私はこれがはるかに健全なアプローチだと思うので<leader>p、再マッピングの代わりにマップするソリューションを提案しましたp。関数SaveFileはでクリップボードを検査しxclipます。画像ファイルがある場合はimg/imageN.<ext>、ファイルが既に存在しない限り、に保存されます。また、*レジスターに[](img/...)テキストを入力して貼り付けます。

nnoremap <silent> <leader>p :call SaveFile()<cr>

function! SaveFile() abort
  let targets = filter(
        \ systemlist('xclip -selection clipboard -t TARGETS -o'),
        \ 'v:val =~# ''image''')
  if empty(targets) | return | endif

  let outdir = expand('%:p:h') . '/img'
  if !isdirectory(outdir)
    call mkdir(outdir)
  endif

  let mimetype = targets[0]
  let extension = split(mimetype, '/')[-1]
  let tmpfile = outdir . '/savefile_tmp.' . extension
  call system(printf('xclip -selection clipboard -t %s -o > %s',
        \ mimetype, tmpfile))

  let cnt = 0
  let filename = outdir . '/image' . cnt . '.' . extension
  while filereadable(filename)
    call system('diff ' . tmpfile . ' ' . filename)
    if !v:shell_error
      call delete(tmpfile)
      break
    endif

    let cnt += 1
    let filename = outdir . '/image' . cnt . '.' . extension
  endwhile

  if filereadable(tmpfile)
    call rename(tmpfile, filename)
  endif

  let @* = '[](' . fnamemodify(filename, ':.') . ')'
  normal! "*p
endfunction

このソリューションは私のために黙って失敗します:(
Maxim Kochurov 2017

おそらく古いバージョンのを使用していると思いますxclipxclip端末でコマンドを実行する必要があります。
Karl YngveLervåg17年

1

上記の回答に基づいて、MacOSとLinuxの問題をvimで解決するためのプラグインを作成しました。このプラグインがお役に立てば幸いです。また、貢献や機能のリクエストにも感謝します。


これまでに見たことはないと思います。READMEのクレジットをありがとう!私もプラグインを書き始めましたが、計画していたすべての機能を実装することはできませんでした。
リッチ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.