Org Capture: prompt for information when determining the target file - emacs

I'm looking to build a capture template that, when run, prompts the user for more information to determine the path of the target file.
I have a few pieces already.
A function which asks the user for data and returns a string:
(defun my/get-121-orgfile ()
"Ask the user for the name of the participant so that we can build"
(interactive)
(read-string "Participant Name: ")
)
An org-capture-template which will run the prompt successfully when emacs loads:
(setq org-capture-templates
`(
("m1" "1-1 meetings")
("m1b" "prep for a 1-1 meeting" entry
(file ,(concat "~/org/meetings/1-2-1/" (my/get-121-orgfile) ".org"))
(file "~/org/templates/meeting-121-prep.org")
:clock-in t)
))
I took the back quote and comma pattern from this SO answer, but I haven't been able to figure out how to scope this behaviour to when I select the template: I want the prompt to pop up each time I hit <org-capture>m1b.

The backquote-comma pattern will not help here: it will call the function at the time that org-capture-template is set. What you are trying to do is to call the function when the capture is executed.
The only way I know to do that would to use the (function foo) target mechanism of org-capture-templates. The doc string says:
(function function-finding-location)
Most general way: write your own function which both visits
the file and moves point to the right location
So you would not be able to use the (file ...) target as you do above. Instead you have to write a function that gets all the information you want and then visit the target file at the target location and add the filled-out template.
This is not a complete answer but it was too long for a comment, but maybe it helps to point you in the right direction.

Related

Grabbing subheaders in org-mode capture template.

I'm using org-mode to write some prose. I'm using the org-capture templates as a convenient way to make notes about edits I need to make later. As I am writing, I can quickly capture an idea or make a note about something that needs to be researched later, and then continue writing.
The problem is that the capture template is not grabbing subheadings, so I need to search the entire text to determine where the edit should be.
Here is the current capture template:
("h" "Writing TODO" entry (file+headline "~/Book-Outline.org" "EDITS")
"* TODO - %?\n \%i\n \%a")
The more specific the capture information, the easier it will be to go back to the exact location in the book to make the edits. Additional ideas or suggestions are appreciated if the capture templates will not do this.
The solution I use is something like:
("h" "Writing TODO" entry (file+headline "~/Book-Outline.org" "EDITS")
"* TODO - %?\n %i\n[[%l][In file %f]]")
It creates an org link to the file when org-capture was called
From Emacs doc here
%l: like %a, but only insert the literal link.
%f: file visited by current buffer when org-capture was called.
Another possible explanation:
In my Org templates I do not use \, maybe you can try to replace your \%a by %a, without the \. (I have not checked that, sorry).
Maybe i'm not getting your point, but normally you should start the capture and in the capture buffer, you can press C-c C-w to refile the capture, then navigate through your org-file until you reached the desired destination.
Org will save your capture then there.
Is that not what you want?

Loading drawing program through emacs

I'm looking for a way to integrate a drawing program with emacs. I often write lecture notes in LaTeX using emacs. The problem is that when the presenter draws a diagram I start to scramble to draw out the diagram, save it, and type the location into my TeX file in a reasonable time.
Is it possible to set up emacs such that when I press a key combination a drawing program will load (e.g. pinta) and once I draw the diagram, the file will automatically save in the folder of the emacs file and the name of the file will be inserted into emacs through
\includegraphics{File_Name}
If this feature is too difficult to implement please let me know as well (I'm also more than happy to try to out variations of this idea).
EDIT in response to comments: My operating system is Ubuntu 14.04 and the absolute path my drawing program is /usr/bin/pinta
Initial Draft -- Not Fully Tested -- Prototype (June 22, 2014):  The following is a first rough draft / not fully tested protype of the concept function idea outlined in the comment beneath the question by the original poster. Because #lawlist does not have an Ubantu OS set-up, or pinta installed, the last part of the function is untested -- i.e., (start-process "open-in-pinta" nil "/usr/bin/pinta" my-new-filename). If there are additional command-line arguments needed for that start-process statement to work on Ubantu, please let me know. The variable form-graphic-file needs to have the absolute path to an already existing blank file created with the pinta program -- that file should be saved in a forms directory somewhere chosen by the user. The function copy-graphic is a modification of the function dired-do-create-files.
TODO:
Verify functionality of the start-process statement.
Convert variable form-file-graphic from a list to a string format and revise copy-graphic function accordingly.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; \includegraphics{File_Name}
(defvar form-file-graphic "~/forms/my-empty-image.ora"
"Absolute path to existing blank graphic file previously created with `pinta'.")
(defun copy-graphic (target)
"This function is a modification of `dired-do-create-files'."
(interactive
(list (expand-file-name (read-file-name "Copy to: " nil "diagram.ora"))))
(copy-file form-file-graphic target)
(insert "\\includegraphics{" (file-relative-name target) "}\n")
(start-process "open-in-pinta" nil "/usr/bin/pinta" target))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

How to automatically track links in org-mode to gnus messages?

I use org-mode + gnus + Gmail for my daily GTD routine. The concept is that treating all incoming messages as tasks, and converting all messages in INBOX into org-mode's tasks using org-capture. Once all new messages are converted into tasks, archive them, and hopefully INBOX is kept zero.
My workflow is as follows:
Open the summary view of gnus INBOX, and select a new message
Capture the message with org-store-link (C-c l)
Open my todo file (todo.org), and create a new task for it, and paste the captured link to the task's body with org-insert-link (C-c C-l)
Go back to gnus summary view and archive the message (B del)
The problem is that when moving a message into the archive folder, the captured link becomes broken, and I cannot follow the link anymore. This is because the captured link includes the IMAP folders' name and archiving message changes the message's IMAP folder name. E.g.,
Captured link: [[gnus:nnimap%2Blocalhost:%5BGmail%5D.Important#1364607772002.9702fb8c#Nodemailer][Email from Geeklist Team: Geekli.st Suggestions & Activi]] (IMAP folder name is "[Gmail]Important")
Link to archived message: [[gnus:nnimap%2Blocalhost:%5BGmail%5D.All Mail#1364607772002.9702fb8c#Nodemailer][Email from Geeklist Team: Geekli.st Suggestions & Activi]] (IMAP folder name is "[Gmail]All Mail")
So my question is: how can I update the captured link automatically when the message is moved to other folders? I guess there are some hooks to do this, but I could not find a good sample for this purpose. Or any simpler solutions for this kind of routine are welcome. TIA.
I do not use 'org-store-link' and 'org-insert-link' but a capture template, that automatically generates a link to the message (%a below). So you do not have to switch buffers to store a TODO entry:
(setq org-capture-templates
'(
("m" "TODO from Mail" entry (file+headline "~/gitfiles/org/gtd.org" "Inbox")
"* TODO %?, Link: %a")))
Since all my emails arrive in the INBOX and are archived in the folder "Archive" I can just use the following function which replaces the string 'INBOX' by 'Archive' in the Org mode link in the capture buffer:
(defun hs/replace ()
(interactive)
(goto-char 1)
(replace-string "INBOX" "Archive"))
This hook calls the function when I hit C-c C-c to file the capture entry:
(add-hook 'org-capture-prepare-finalize-hook 'hs/replace)
So, my workflow is as follows:
Select a message in Summary buffer
Hit C-c c m to capture a TODO item with Link to message and write a description (since the message is still in the inbox, the generated link contains the group "INBOX")
Hit C-c C-c to file the TODO entry (this calls the function 'hs/replace' which replaces the string INBOX by Archive)
Archive the email in the archive folder.
HTH

Lisp: creating a macro to cycle through a created list per document

Let's say I want to create a new document, and cycle quickly through a list.
If it's only for one "word", I think there should be a general way to do this.
For instance:
"blue orange red yellow black white"
Does anyone know a way how to cycle through those items when I create:
\begin{orange}
... and I want to press a key to cycle through this list, replacing orange with the next item on the list (doing this procedure in the opposite direction wouldn't be hard then)?
I tried many different ideas with macro's (placing the list on the top of the document, and doing a whole bunch of i-searches), but that doesn't cut it.
I'd be willing to put the list in an elisp file, though I have no clue how to use that variable from elisp in, let's say, a LaTeX document (.tex).
Well, this might be possible, but depends on how much effort you are willing to put into writing eLisp code to make it work. It's not possible by just some configuration option. I would be looking into extending autocomplete by adding new sources to it, something like:
(defvar tex-tag-ac-sources
'((init . tex-tag-ac-init)
(requires . 0)
(candidates . tex-tag-ac-candidates)
(document . tex-tag-ac-documentation)
(match . tex-tag-completion-filter)
(prefix . tex-tag-ac-prefix-matcher)
(symbol . "s"))
"The source generator for autocompletion needed for interaction
with auto-complete")
Where tex-tag-ac-candidates, tex-tag-ac-documentation, tex-tag-completion-filter and tex-tag-ac-prefix-matcher are function that do autocompletion. I.e. init function is called once when the autocompletion process starts for a specified prefix. It's called w/o arguments. The candidates is the function that is responsible for showing the filtered list of candidates, it's called w/o arguments, you would filter the candidates in the filter function, it is called with the prefix collected so far and the list of candidates so far. Lastly, the matcher function is invoked on the text of the file to see if the completion is needed at point. So, if it returns t, the init is called, and then loops through filter-candidates as you type.
While this is a bit involved... you'd definitely have a completion for anything you want. Obviously, if those functions in source are defined by you, then, if you wanted to, you could read completion arguments dynamically or have them generated dynamically in some way.
Ah, you would add the sources to autocomplete by something like:
(auto-complete (list tex-tag-ac-sources))
if doing it on per call basis, or
(setq ac-sources (list tex-tag-ac-sources <other sources>))
You can find more info here: http://cx4a.org/software/auto-complete/manual.html#Using_Source
EDIT: I translated the macro into a function.
Here is a way I did it. I created a file called "list.list" where my "lists" are saved. I saved the LaTeX templates for Beamer in there. I inserted them like this:
Antibes Bergen Berkeley Berlin ..... Antibes
Note that you should always put the first entry in twice to allow it to loop.
Here is the code:
(defun cycle-list-word ()
(interactive)
(right-word)
(backward-kill-word 1)
(find-file "/emacs-24.1/list.list")
(search-forward (substring-no-properties (car kill-ring)) nil t)
(right-word)
(backward-kill-word 1)
(bury-buffer)
(yank)
)

How can I make Emacs query the user before saving a file (and abort if the user answers no)?

I want to add an extra prompt asking the user if they are sure they want to save the file, but only for files in certain "protected" directories. Assume I have a function file-needs-protection-p that takes a file name and returns t if the user should be queried before saving that file. How can I get Emacs to ask something like "This file is protected. Are you sure you want to modify it?" when the user tries to save such a file, and then make Emacs abort the save if the user answers no?
Hopefully there is some special hook somewhere where I can add a function that uses yes-or-no-p, and Emacs will abort the save if the function returns false?
Untested, but I think you should be able to use before-save-hook to perform your test and ask your question, and simply raise an error if they answer no:
(error "Save aborted by user")
If you've got file-needs-protection-p already, I think the rest is straightforward:
(defun save-buffer-check
"If the current buffer is a protected file, query the user before saving."
(if (file-needs-protection-p (buffer-file-name))
(if (y-or-n-p
"This file is protected. Are you sure you want to modify it?")
(save-buffer))
(save-buffer)))
Rebind that to C-x C-s and see if it does what you need. I don't think you need any special hooks or advice, just a function that inserts a call to your predicate before either calling save-buffer or just returning without doing anything.