From b7ac1364890ed81b41ba203805861ee097f7859a Mon Sep 17 00:00:00 2001 From: Matthew Flower Date: Fri, 11 Feb 2022 18:05:43 -0500 Subject: [PATCH] Add support for Pasting Images on Mac. Also, fix relative paths for images when markdown is in daily and there is an image subdir. --- README.md | 6 ++-- lua/telekasten.lua | 89 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 83 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c628c1e..a147810 100644 --- a/README.md +++ b/README.md @@ -138,8 +138,8 @@ See below for installing and using it. #### 0.0.3 For pasting images: xclip (optional) -Telekasten.nvim supports pasting images from the clipboard. Currently, this is only implemented for systems that have -the `xclip` utility installed. +Telekasten.nvim supports pasting images from the clipboard. Currently, this is implemented for systems that have +the `xclip` utility installed or on macs. On Ubuntu/Debian like systems: @@ -147,6 +147,8 @@ On Ubuntu/Debian like systems: sudo apt-get install xclip ``` +On Macs, you should not install a separate tool. Installing xclip will prevent this feature from working properly. + --- #### 0.0.4 For image previews: telescope-media-files.nvim (optional) diff --git a/lua/telekasten.lua b/lua/telekasten.lua index fbfc50b..9ed77f4 100644 --- a/lua/telekasten.lua +++ b/lua/telekasten.lua @@ -274,12 +274,74 @@ end -- ---------------------------------------------------------------------------- -- image stuff +-- ---------------------------------------------------------------------------- + +local function make_relative_path(bufferpath, imagepath, sep) + sep = sep or "/" + + -- Split the buffer and image path into their dirs/files + local buffer_dirs = {} + for w in string.gmatch(bufferpath, "([^" .. sep .. "]+)") do + buffer_dirs[#buffer_dirs + 1] = w + end + local image_dirs = {} + for w in string.gmatch(imagepath, "([^" .. sep .. "]+)") do + image_dirs[#image_dirs + 1] = w + end + + -- The parts of the dir list that match won't matter, so skip them + local i = 1 + while i < #image_dirs and i < #buffer_dirs do + if image_dirs[i] ~= buffer_dirs[i] then + break + else + i = i + 1 + end + end + + -- Append ../ to walk up from the buffer location and the path downward + -- to the location of the image file in order to create a relative path + local relative_path = "" + while i <= #image_dirs or i <= #buffer_dirs do + if i <= #image_dirs then + if relative_path == "" then + relative_path = image_dirs[i] + else + relative_path = relative_path .. sep .. image_dirs[i] + end + end + if i <= #buffer_dirs - 1 then + relative_path = ".." .. sep .. relative_path + end + i = i + 1 + end + + return relative_path +end + local function imgFromClipboard() if not global_dir_check() then return end - if vim.fn.executable("xclip") == 0 then + local get_paste_command + if vim.fn.executable("xclip") == 1 then + get_paste_command = function(dir, filename) + return "xclip -selection clipboard -t image/png -o > " + .. dir + .. "/" + .. filename + end + elseif vim.fn.executable("osascript") == 1 then + get_paste_command = function(dir, filename) + return string.format( + 'osascript -e "tell application \\"System Events\\" to write (the clipboard as «class PNGf») to ' + .. '(make new file at folder \\"%s\\" with properties {name:\\"%s\\"})"', + dir, + filename + ) + end + else vim.api.nvim_err_write("No xclip installed!\n") return end @@ -316,23 +378,30 @@ local function imgFromClipboard() -- 00000090 10 66 d7 01 b1 e4 fb 79 7c f2 2c e7 cc 39 e7 3d |.f.....y|.,..9.=| local pngname = "pasted_img_" .. os.date("%Y%m%d%H%M%S") .. ".png" - local pngpath = M.Cfg.home .. "/" .. pngname - local relpath = pngname + local pngdir = M.Cfg.image_subdir and M.Cfg.image_subdir or M.Cfg.home + local png = pngdir .. "/" .. pngname + local relpath = make_relative_path(vim.fn.expand("%"), png, "/") - if M.Cfg.image_subdir then - relpath = Path:new(M.Cfg.image_subdir):make_relative(M.Cfg.home) - .. "/" - .. pngname - pngpath = M.Cfg.image_subdir .. "/" .. pngname + local result = os.execute(get_paste_command(pngdir, pngname)) + if result > 0 then + vim.api.nvim_err_writeln( + string.format( + "Unable to write image %s (exit code: %d). Is there an image on the clipboard? ", + png, + result + ) + ) + return end - os.execute("xclip -selection clipboard -t image/png -o > " .. pngpath) - if file_exists(pngpath) then + if file_exists(png) then if M.Cfg.image_link_style == "markdown" then vim.api.nvim_put({ "![](" .. relpath .. ")" }, "", true, true) else vim.api.nvim_put({ "![[" .. pngname .. "]]" }, "", true, true) end + else + vim.api.nvim_err_writeln("Unable to write image " .. png) end end -- end of image stuff