[求助] 关于 WSL 中使用 org-download 保存屏幕截图

我抄了这个链接里的配置,

(org-download-screenshot-method "powershell.exe -Command \"(Get-Clipboard -Format image).Save('$(wslpath -w %s)')\"")

执行 org-download-screenshot 报错

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  org-download-screenshot()
  funcall-interactively(org-download-screenshot)
  command-execute(org-download-screenshot)

经过测试 org-download-screen-method 在 fish 中是可以正确执行的。

我还在 fish 中自定义了一个函数

function save_clipboard_image
                  set imagepathwindows (wslpath -w $argv)
                  powershell.exe -Command "(Get-Clipboard -Format image).save('$imagepathwindows')"
              end

这个函数在 emacs 中使用 shell-command 执行可以成功,但指定它为 org-download-screen-method 有同样的报错。

上面那个链接里自定义的插入图片函数我试了也不行,图片没有被保存到wsl中。

目前的插入图片方法是我用 org-download-image 写了一个函数,

(defun org-download-windows-image (windows_path)
    "Download an image from a Windows path and insert it into the current Org file."
    (interactive "sWindows Path: ")
    (let ((path (substring (shell-command-to-string (concat "wslpath " windows_path)) 0 -1)))
  (org-download-image path)))

可以输入图片在 Windows 中的路径把它插入到 org 里。但这样插入截图要先保存下来,再复制路径粘贴到 emacs 中,非常麻烦。

不知道是哪里出了问题,尝试了几天都没有办法,希望有大佬能帮忙解决。

没有解决,不知道为什么 org-download-clipboard 不能使用。我写了个脚本自动把剪贴板的图片保存下来,再用 org-download-image 来插入,有更好的办法请不吝赐教。

1 个赞

我使用方案是覆盖 org-download-clipboard 方法, 利用 imagemagick 库将 bmp 格式转换为 png 格式.

(use-package! org-download
  :config
  (when IS-WSL
    (setenv "XDG_SESSION_TYPE" "wayland")
    (after! org-download
      ;;; 修复 WSL 下粘贴剪贴板中的图片错误
      (defun org-download-clipboard (&optional basename)
        "Capture the image from the clipboard and insert the resulting file."
        (interactive)
        (let ((org-download-screenshot-method
               (if (executable-find "wl-paste")
                   "wl-paste -t image/bmp | convert bmp:- %s"
                 (user-error
                  "Please install the \"wl-paste\" program included in wl-clipboard"))))
          (org-download-screenshot basename))))))

为什么剪贴板源图片是bmp格式的, 是因为 wslg 使用的是 weston 作为 wayland 窗口管理器. 其只支持 image/bmp 图片格式类型.

WSLg Github issue – Copying images to wayland apps pastes only BMP images

源码: weston-mirror/libweston/backend-rdp/rdpclip.c at 603601f2fe63e43f57a58cef6c880d054731dc6e · microsoft/weston-mirror · GitHub xclip 不知道为什么 TARGETS 不支持任何图片格式,所以不能使用 org-download 包中X11平台的粘贴工具.

希望能帮到你

awerdx的方法挺聪明的,只是修改org-download-clipboard函数。不过似乎XDG_SESSION_TYPE 其实应该在shell的环境变量里设置,这样如果是使用wayland就可以做一区别。从org-download的源代码看,x11使用了xclip,wayland使用的是wl-paste。我修改了一下。

(use-package org-download
  :config
  (if IS-WSL
	;;(setenv "XDG_SESSION_TYPE" "wayland")
	;; Windows 11 sniptshot use imge/bmp instead of png 
	(defun org-download-clipboard (&optional basename)
	  "Capture the image from the clipboard and insert the resulting file."
	  (interactive)
	  (let ((org-download-screenshot-method
		 (if (executable-find "wl-paste")
		     "wl-paste -t image/bmp | convert bmp:- %s"
		   (user-error
		    "Please install the \"wl-paste\" program included in wl-clipboard"))))
	    (org-download-screenshot basename)))))

不过,如果还是使用WSL的判断机制,system-type识别不了,它会认为是gnu/linux,所以还是识别WSL_DISTRO_NAME吧。

(defvar IS-WSL nil  
  "Flag indicating whether we are running inside WSL with the expected distro.")  
  
(let ((expt-distro "Ubuntu"))  
  (when (and (getenv "WSL_DISTRO_NAME")  
             (string= (getenv "WSL_DISTRO_NAME") expt-distro))  
    (setq IS-WSL t))) 

大家还有什么好办法。

另外,借这楼问个问题,drag and drop有什么好办法么? 毕竟,拖拽就会给stop signstop