emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Capture with (moving) attachment?
@ 2020-07-22 21:48 Tim Landscheidt
  2020-07-28  9:28 ` Mikhail Skorzhinskii
  0 siblings, 1 reply; 2+ messages in thread
From: Tim Landscheidt @ 2020-07-22 21:48 UTC (permalink / raw)
  To: emacs-orgmode

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



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Capture with (moving) attachment?
  2020-07-22 21:48 Capture with (moving) attachment? Tim Landscheidt
@ 2020-07-28  9:28 ` Mikhail Skorzhinskii
  0 siblings, 0 replies; 2+ messages in thread
From: Mikhail Skorzhinskii @ 2020-07-28  9:28 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: Tim Landscheidt

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."
    (save-excursion
      (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
        (org-capture))
      ;; Create as many new headings as it need to be created
      (when (> (length files) 1)
        (save-excursion
          (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)))
            (org-edit-headline
             (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 moved
      (org-capture-finalize)
      ;; Go to the file if we want to say something about it
      (org-capture-goto-last-stored)
      ;; Save buffer just in case
      (save-buffer)))

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

#!/bin/bash

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

files=

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

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]
Type=Service
ServiceTypes=KonqPopupMenu/Plugin
MimeType=all/all;
Actions=org-attach-mv;
X-KDE-Priority=TopLevel

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

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






^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-07-28  9:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-22 21:48 Capture with (moving) attachment? Tim Landscheidt
2020-07-28  9:28 ` Mikhail Skorzhinskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).