In markdown files, you can insert an image by writing
![alt text](/path/to/image), but doing this task manually is quite cumbersome. Let me state the manual steps first to make you understand why this is cumbersome.
1. Take screenshot
2. Save it at proper location
3. Mention the image in the markdown using the above mentioned syntax, i.e
Now, I wanted to complete the all the above steps in least number of keystrokes, in one step! Let me explain how I did it, then I’ll also explain what challenges I faced in the meanwhile. All the steps were performed on Ubuntu 20, hence it might differ from OS to OS. Also, this was a great learning experience for me, hence want to document it the best way possible.
I thought of trying out this vim plugin but it was surprisingly not working. Then I read the documentation properly which led me to the genesis of this plugin which is this stack exchange answer. Then I started following this answer, understood the vimscript then added it to my
vimrc but, it was still not working :(
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 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
Upon investigating it further I readlized that it was missing
! infront of
() while inserting the image in the script, but, even after updating the vimscript it was still not working!
Then I tried to figure out if my vim system register was working properly. It turns out my vim version does not support clipboard! (You can check this by running
vim --version | grep clipboard, then see it is
+clipboard). Hence I had to install
vim-gtk to enable this feature. I’ve raised an issue in the project to specify this issue. Now I was able to paste the data stored in system clipboard to vim buffer and vice-versa.
But it turns out I was still not able to copy screenshot using the default tool, but able to paste in vim buffer yet. Now I need to solve the copy problem!
gnome-screenshot which allows you to capture portion of the screen (IMHO most flexible way to take screenshot) and then paste it anywhere I want. But, after lots of frustration I understood that
gnome-screenshot is taking the screenshot but it is not being copied to
xclip clipboard manager which is what I am using to paste the screenshot in vim buffer. I order to get around this I had to assign a keyboard shortcut to the following command to take screenshot and place it in xclip
gnome-screenshot -acf /tmp/test && cat /tmp/test | xclip -i -selection clipboard -target image/png
Ultimately now it worked! Now I can take screenshot using the custom keyboard shortcut (which pops up a terminal too) and then paste it using
<leader>p in vim since I have mapped it this way in my vimrc.
It was complicated and took me a lot of time to figure it out but it offered me chance to learn many things. If you know how to do it better please let me know, or, if you find similar issue, tweet to me or DM me on LinkedIn, I would be happy to help!