Fügen Sie beim Bearbeiten von Markdown einen Link zum Bild in die Zwischenablage ein

9

Ich habe ein Bild in der Zwischenablage und möchte es als Text in mein Dokument einfügen [](img/image1.png).

Anstatt es zuerst in dieses Verzeichnis zu kopieren, möchte ich es mit einem einzigen pTastendruck in Vim tun . Es hakt also p, prüft, ob ich eine Markdown-Datei bearbeite, speichert das Bild aus der Zwischenablage am Speicherort img/image1.pngund fügt es [](img/image1.png)in die Datei ein.

Ist das mit Vim möglich?

Ich benutze MacOS und Terminal Vim.

Maxim Kochurov
quelle
Ist dies aus Gründen der Klarheit "Ich habe ein Bild direkt wie in einem Wort kopiert" oder "Ich habe eine Bilddatei im Finder kopiert"? (Ich weiß nicht wirklich, ob sie unterschiedlich sind ...)
Joe

Antworten:

2

Der übliche Terminalbefehl für den Zugriff auf die Zwischenablage auf dem Mac lautet pbpaste. Dies funktioniert jedoch nicht für Bilddaten, daher müssen wir auf AppleScript zurückgreifen:

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

Fügen Sie den obigen Code zu hinzu ~/.vim/after/ftplugin/markdown.vim.

Dadurch werden die Zwischenablagedaten in der Datei "img / image1.png" gespeichert, wenn sie PNG-Daten enthalten. Es wird dann nur das verwendet :normal!, um den gewünschten Markdown-Link einzufügen.

Wenn die Zwischenablage keine PNG-Daten enthält (oder wenn wir uns nicht in einer Markdown-Datei befinden), führt sie einen regulären pBefehl aus.

Wenn ich dies verwenden würde, würde ich es aufräumen, um weitere Bildtypen zu unterstützen und den Cursor an einer hilfreicheren Position zu belassen, aber dies funktioniert gut als Proof of Concept.

(Ich würde auch ein <leader>pMapping verwenden, wie von Karl Yngve Lervåg vorgeschlagen  - dies scheint eine Funktionalität zu sein, die ich lieber speziell aufrufen würde - aber das haben Sie nicht verlangt).

Weiterführende Literatur

Reich
quelle
Schön, ich habe meine Antwort mit einem Link zu Ihrer aktualisiert, da Ihre Lösung tatsächlich die MacOS-Anforderungen erfüllt.
Karl Yngve Lervåg
1
@ KarlYngveLervåg Danke, das ist sehr nett von dir. Ohne Ihre hätte ich meine Antwort nicht einmal geschrieben: Sie haben mich dazu inspiriert, eine native Mac-Lösung zu finden!
Rich
3

Die folgende Lösung sollte auf den meisten Linux-Systemen funktionieren. Es erfordert ein relativ aktualisiertes xclipTool. Eine Lösung für MacOS / OSX finden Sie in der Antwort von @ Rich .


Ich habe eine Lösung vorgeschlagen, die Karten <leader>panstelle von Neuzuordnungen enthält p, da ich dies für einen viel vernünftigeren Ansatz halte. Die Funktion SaveFileüberprüft die Zwischenablage mit xclip. Wenn eine Bilddatei vorhanden ist, wird diese gespeichert img/imageN.<ext>, sofern die Datei nicht bereits vorhanden ist. Außerdem wird das *Register mit dem [](img/...)Text gefüllt und anschließend eingefügt.

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
Karl Yngve Lervåg
quelle
Diese Lösung schlägt für mich lautlos fehl :(
Maxim Kochurov
Ich vermute, dass Sie eine alte Version von haben xclip. Sie sollten versuchen, die xclipBefehle in Ihrem Terminal auszuführen.
Karl Yngve Lervåg
1

Basierend auf den obigen Antworten habe ich ein Plugin für vim erstellt, um mein Problem für Macos und möglicherweise für Linux zu lösen. Ich hoffe, Sie finden dieses Plugin hilfreich. Ich freue mich auch über Beiträge und Feature-Anfragen.

Maxim Kochurov
quelle
Ich glaube nicht, dass ich das jemals zuvor gesehen habe. Vielen Dank für die Gutschrift in Ihrer README! Ich habe auch angefangen, ein Plugin zu schreiben , bin aber nie dazu gekommen, alle geplanten Funktionen zu implementieren.
Rich