emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Mikhail Skorzhinskii <mskorzhinskiy@eml.cc>
To: emacs-orgmode@gnu.org
Cc: Tim Landscheidt <tim@tim-landscheidt.de>
Subject: Re: Capture with (moving) attachment?
Date: Tue, 28 Jul 2020 11:28:37 +0200	[thread overview]
Message-ID: <2956402.ksTVMsbfjo@trex230> (raw)
In-Reply-To: <874kpz8f54.fsf@passepartout.tim-landscheidt.de>

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






      reply	other threads:[~2020-07-28  9:33 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-22 21:48 Capture with (moving) attachment? Tim Landscheidt
2020-07-28  9:28 ` Mikhail Skorzhinskii [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2956402.ksTVMsbfjo@trex230 \
    --to=mskorzhinskiy@eml.cc \
    --cc=emacs-orgmode@gnu.org \
    --cc=tim@tim-landscheidt.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).