[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Capture with (moving) attachment?

From: Mikhail Skorzhinskii
Subject: Re: Capture with (moving) attachment?
Date: Tue, 28 Jul 2020 11:28:37 +0200

Hi Tim,

I tried to solve the similar problem and come up with the solution with 
external script to do this. This is basically only tested in Linux with KDEv5 
environment, but could be extended to any other DE or to work solely in emacs.

Anyway, the idea of the solution is to provide an interface to the graphical 
file manager, so you can select files and just "send them" to org-mode. For 
this I wrote elisp function that do the attaching on files you provided, then a 
script that pass arguments to this function via emacslcient and then a module 
for file manager for menu to appear.

1. Elsip function for the attaching:

(defun org-user/move-to-file-storage (files)
  "Move FILES at my file system to annex/org file storage."
      (let ((org-capture-templates org-file-capture-templates)) ;; << don't use 
org-file-capture-template if you don't want separate capture templates variable 
for this
      ;; Create as many new headings as it need to be created
      (when (> (length files) 1)
          (org-clone-subtree-with-time-shift (- (length files) 1) '(4))))
      ;; Edit these headings and attach files to them
      (dolist (file files)
        (when (file-exists-p file)
          ;; Just some sane name should be enough
          (org-edit-headline (concat "File: " (file-name-nondirectory file)))
          ;; Attach file to the storage room
          (org-attach-attach file nil 'mv)
          ;; Edit headline once again with the stored file
          (let* ((attach-dir (org-attach-dir))
                 (files (org-attach-file-list attach-dir))
                 (file (pop files)))
             (format "[[attachment:%s][%s]]" file (org-get-heading t t t t))))
          ;; Go to the next free heading
          (org-next-visible-heading 1)))
      ;; Make sure that we didn't cancel capture with file that was already 
      ;; Go to the file if we want to say something about it
      ;; Save buffer just in case

Function implementation is very far from ideal, but it is working to some 
extent. There is a bug with this function: it inserts one empty headline. 
Should be easy to fix, sorry about that.

2. Define your capture templates

Just like the normal capture templates.

(setq org-file-capture-templates ... )

Now calling this function externally will attach files you provided, save org 
buffers immediately after and leave the frame open on last attached item. Every 
attached file will have separate heading. And every heading will be a link to 
the attached file.

3. Store this script somewhere in your $PATH


# Author: Mikhail Skorzhinskii <mskorzhinskiy@eml.cc>
# Description: Attach file to the org-mode file storage


for file in "$@"; do
    files="${files} \"${file}\""

emacsclient -a "" -c -F '((name . "doom-capture"))' \
    -e "(org-user/move-to-file-storage (list ${files}))"

If you save it as "org-attach-files.sh" then you can call it like 

  org-attach-files.sh file1 file2 file3

But make sure to pass absolute paths, as emacs executable will probably 
operating in different directory. I personally don't care as file manager 
always call it with full paths. But easy to fix with readlink -e call. (i.e. 
file=`readlink -e ${file}` before putting it to ${files}.

4. Place this module to .local/share/kservices5/ServiceMenus/emacs.desktop

End name can be anything of course.

[Desktop Entry]

[Desktop Action org-attach-mv]
Name=Send to git-annex
Exec=emacs-org-attach-file %U

This should work in KDE files managers (like Dolphin). Right-click the file and 
you will have "Send to git annex" menu item.

Mikhail Skorzhinskii

On Wednesday, July 22, 2020 11:48:24 PM CEST Tim Landscheidt wrote:
> Hi,
> I have a capture template to file items to a list:
> | ("i" "inventory" entry
> | 
> |  (file "~/Desktop/Agenda/Inventar.org")
> |  "* %^{Name}" :immediate-finish t)
> Currently, when I want to file an item with an associated
> image, I open the directory of the images with dired, visit
> the image file, use the capture to add an item, kill the im-
> age buffer, use M-0 w in dired to copy the file's name,
> switch to the org file, use C-c C-a m to attach the image by
> moving the file, and then switch back to the dired buffer.
> Lather, rinse, repeat, until the directory with the images
> is empty.
> What I want to do instead is open the image file (via dir-
> ed), have the capture do the attaching by itself (if it is
> called in an image-mode buffer) and then kill the image
> buffer.  (Emacs does not care if the file associated with
> the buffer is deleted in the mean time.)
> First idea was to use %(EXP) to set
> org-capture-after-finalize-hook to attach the file, but that
> hook is called in the original (image) buffer.
> org-capture-before-finalize-hook on the other hand is called
> in a CAPTURE-Inventar.org buffer (with no associated file),
> same with org-capture-prepare-finalize-hook.  (I also would
> like to perform the attaching only *after* the item has suc-
> cessfully been filed to avoid misfiling/deleting image
> files.)
> There are other ways to achieve this in this particular case
> (capture, visit the org file, go to (point-max),
> (org-attach-attach file nil 'mv), maybe even replace capture
> with an (insert (format "* %s\n" (read-string)))), but are
> there general solutions for this issue that will work, well,
> more generally?
> TIA,
> Tim

reply via email to

[Prev in Thread] Current Thread [Next in Thread]