2022-01-01 ,

org-downloadで保存前にファイル名を入力する

私はこれまでorg-downloadを保存するファイル名が「orgファイル名_タイムスタンプ_ダウンロードファイル名」 になるように設定して使っていたのですが、十中八九後からファイル名を変更しなければならなくていちいちファイルとリンクの両方を修正しなければならず面倒くさいなーと思っていました。

よく考えたらorg-download-file-format-function変数に指定する関数内でread-file-nameを呼び出せば良いだけですね。この変数はなぜかdefcustomではなくdefvarなのですが、使っているのはfuncallする一箇所だけ。カスタマイズするのに使っても問題ないように見えます。私はファイル名にorgファイル名を入れるために既に書き替えていたのでそこを修正すれば良いだけでした。

(setq org-download-file-format-function 'my-org-download-file-format)
(defun my-org-download-file-format (filename)
  (read-file-name
   "File Name: "
   nil nil nil
   (concat
    (if-let ((fn (buffer-file-name)))
        (concat (file-name-base fn) "_"))
    (format-time-string "%Y%m%d_%H%M%S_")
    filename)))

ついでに前回作ったメニュー(org-cmenu)に登録。

これまでHydraでorg-download用のメニューを作っていたので、それをtransientに書き替えてorg-cmenuのInsertメニューに追加しました。

現在の設定はだいたいこんな感じ。

(autoload #'org-download-clipboard "org-download")
(autoload #'org-download-yank "org-download")
(require 'transient)
(transient-define-prefix my-org-download ()
  "Insert an image."
  ["Copy an image from:"
   ("c" "Clipboard" org-download-clipboard)
   ("y" "Full-path or URL on kill-ring" org-download-yank)
   ("a" "All monitors" my-org-download-screenshot-all)
   ("p" "Primary monitor" my-org-download-screenshot-primary)
   ("f" "Foreground window" my-org-download-screenshot-active-window)
   "or drop from a local image file."])

(with-eval-after-load "org-cmenu-setup"
  (transient-append-suffix
    'org-cmenu-insert
    '(0 -1 -1) ;;Insertメニューの一番最後に追加
    '("D" "org-download" my-org-download)))

(defun my-org-download-screenshot-all ()
  (interactive)
  (my-org-download-screenshot "screenshot-all.ps1"))

(defun my-org-download-screenshot-primary ()
  (interactive)
  (my-org-download-screenshot "screenshot-primary.ps1"))

(defun my-org-download-screenshot-active-window ()
  (interactive)
  (my-org-download-screenshot "screenshot-activewin.ps1"))

(defun my-org-download-screenshot (script-name)
  (require 'org-download)
  (let ((org-download-screenshot-method
         (format
          "powershell %s %%s"
          (expand-file-name
           (concat
            my-org-download-script-path ;;別途設定のこと
            script-name)))))
    (message "Waiting 3 seconds...")
    (sleep-for 3)
    (message nil)
    (org-download-screenshot)))

WindowsなのでPowerShellを使用してスクリーンショットを撮っていますが、スクリプトはWindowsのコマンドラインからスクリーンショットを撮る(PowerShell)で紹介したものです。

……あ、今気がついたのですが、org-download-rename-at-pointなんてコマンドがあるんですね。ファイル名とリンクを一緒にリネームしてくれるようです。まぁ、別に毎回ファイル名を確認してくれた方が良いんじゃないでしょうか。沢山の画像をドロップしまくるような使い方をするなら毎回確認されると困るでしょうけど、私はそういう使い方はしませんし。でもファイル名とリンクの同時リネームは便利だからorg-cmenuに加えておこっと。

(追記:追加しました。orgのリンクを書き替えただけでその先のファイル名も変わってるなんてマジカル!)

Add feature to rename linked file · misohena/org-cmenu@8805f27