Call org-ref interactivly in org-capture template - emacs

I want to be be able to call org-ref from within an org-capture template. I have got the org-ref part working, but org-capture is not capturing the reference that is outputted.
I have tried writing org-ref-insert-link as its own function and even to print the output, but org-cature doesn't seem to want to recored anything that org-ref passes.
My current code is:
(setq org-capture-templates
'(("q" "Quotes" entry
(file+headline "~/Dropbox/Org/quotes.org" "Quotes")
"** From: %(call-interactively #'org-ref-insert-link) %?" :prepend t)))
Is there something obvious that I'm missing here? There doesn't seem to be any error output from this, but neither is there a reference.

Related

How to show full path of module

If I do this:
(message (format "===> %s loaded" (file-name-base load-file-name)))
I get just the basename of the file.
===> 0100-start loaded
If I do this:
(message (format "===> %s loaded" 'load-file-name))
I get:
===> load-file-name loaded
Not really what I want ...
If I do this:
(message (format "===> %s loaded" load-file-name))
I get:
===> nil loaded
No clue what is happening there. I though the variable load-file-name has the value of the module where it is used. And it somehow has it, otherwise I could not get the (file-name-base load-file-name), but used by itself does not work. I probably need to backquote-forward-quote-and-precede-with-a-comma the variable name, but no idea how to do this. Elisp witchery.
What I want to get is:
===> /home/user1/.emacs.d/conf/0100-start.el loaded
How to get the full, absolute path of the lisp module? I though this was the job of load-file-name. How can I display it?
How can I use a variable in elisp?
First of all, message can do formatting, so format is not needed.
Second, when you quote a variable, like 'foo, it is not evaluated, so you are not getting its value.
Third, C-h f file-name-base RET should explain your first output.
Finally, the correct forma inside the file being loaded is
(message "===> %s loaded" load-file-name)
and the reason you see nil there is that it was not evaluated during loading. Please try C-h v load-file-name RET.
Scoping Rules for Variable Binding1:
Local bindings in Emacs Lisp have indefinite scope and dynamic extent.
[...]
Indefinite scope means that any part of the program can potentially access the variable binding. Extent refers to when, as the program is executing, the binding exists.
Dynamic extent means that the binding lasts as long as the activation of the construct that established it.
(Emacs can also perform lexical binding)
When you load a file, something like this happens:
(defun load (file)
(let ((load-file-name file))
(do-load file)))
And so, load-file-name is only bound to file during the time the file is being loaded. When the code exists the scope of the let, the binding is no more effective.
Note that if you did not load but require a module, then upon loading Emacs will also register the module as being provided and will not reload it when calling require another time. This might be the reason you get nil the third time (see unload-feature).
In your module, you can define a global binding for your own symbol:
(defvar jeckyll2hide/module-path load-file-name)
Then, the first time you load (or require) your module, you will define a variable that will be globally bound to the value that is locally bound to load-file-name during loading.
1. formatting and emphasis mine

how to prevent helm-swoop from returning symbol at point?

I would like to invoke M-x helm-swoop such that it does NOT return the symbol at point. I find that it always picks up undesired symbols, e.g. when I invoke M-x helm-swoop in org-mode, I get Swoop: \*, and I then have to delete the \* before I can enter my desired search term. How can I do this?
This has been bugging me as well, for exactly the same reason (swoop in an Org-mode buffer picking up heading characters), so this question motivated me to go and look.
Looking at the source, Helm-swoop calls helm-swoop-pre-input-function to populate the prompt, and by default this is set to a function that returns (thing-at-point 'symbol), which is what causes the problem in headings.
A quick test with the following in my init file seems to work:
(setq helm-swoop-pre-input-function
(lambda () nil))
This could certainly be improved by, for example, keeping the default behaviour in non-Org buffers but as I'm only really using swoop in Org buffers this is good enough for me.

elisp code clobbering a buffer, instead of saving off elsewhere... why?

I'm having some difficulties when trying to set something up that saves some persistent state, so that I can use the data between emacs invocations.
Using as a starting point some code from another question, I came up with the following little code snippet for something I'm wanting to do:
(defmacro with-output-to-file (path &rest body)
"record output of commands in body to file"
`(save-excursion
(let* ((buf (find-file-noselect ,path))
(standard-output buf))
(set-buffer buf)
(erase-buffer)
,#body
(save-buffer)
(kill-buffer))))
I then have a function that uses this, like:
(defun my-save-some-data ()
(with-output-to-file my-data-save-file
(prin1 my-data)))
EDIT: These both follow code like the following (previously, these were both setq; thanks to a comment from #phils for inspiring me to switch them to devfar and defcustom):
; note: my actual variable names (and filename value) are different;
; changed for example sake:
(defvar my-data (make-hash-table :test 'equal) "Data for a thing")
(defcustom my-data-save-file "~/tmp/my-data.el" "File to save my data to")
(Note: I also have a function to read the data back in, which happens automatically at load time, or on demand.)
I've set that up to run in a few circumstances (maybe too many? maybe poor choices? Anyway, this is what I set up):
(add-hook 'auto-save-hook 'my-save-some-data)
(add-hook 'kill-emacs-hook 'my-save-some-data)
(add-hook 'post-gc-hook 'my-save-some-data)
Most of the time, this works fine. However, every once in a while, I'm getting a problem where the data gets written to one of my previously-open buffers (killing all previous content there!), and then that buffer gets killed, with the saved changes.
Suffice it to say, this is highly annoying, as the buffer where this happens is frequently somewhere where I've been doing some work, and not necessarily checked it in yet.
I tried altering the macro above, replacing from (set-buffer buf) on with:
(with-current-buffer buf ; because set-buffer wasn't working??
(erase-buffer)
,#body
(if (eq buf (current-buffer))
(progn
(save-buffer)
(kill-buffer))
(message "buffer changed?!"))))))
This has somehow managed to cause it to append to the buffer, instead of overwriting it... so my if statement does seem to be working to some degree... however I don't see the message in my *Messages* buffer, so... I'm not quite sure what's going on.
One thing I think I've noticed (though it's hard to be certain, since I may not be actively paying attention when this happens) is that this happens in a not-then-currently-active buffer, rather than a buffer I'm currently editing.
So, the questions:
Am I doing something wrong here?
Are there other/better ways of doing this?
Are there standard ways to save state in a programatic way, that I could be using? (I poked around a bit in apropos, but failed to find anything... though perhaps I just don't know what to look for.)
What can I do to help myself track this down? (is there a way I can set breakpoints or something?)
Are there other protections I could use in code like this?
Any other thoughts welcome. I'm adding some more (message) forms in hopes of getting more debugging info in the mean time.
UPDATE: I've figured out that this only happens with the post-gc-hook. I don't know if my variables were somehow getting clobbered (and perhaps switching to defvar and defcustom will solve that?), or if there's some sort of obscure bug in the post-gc-hook processing... checking for reproducing the test-case with this latest change.
You can indeed set breakpoints, an easy way to do this is to put (edebug) in the place where you want to break. Then you can use, n for next, SPC for step, and e to eval. You can read more about edebug here.
So you can set a conditional breakpoint as a protection/warning, like this, before your call to (set-buffer):
(when (get-file-buffer my-data-save-file)
(read-from-minibuffer
(format "Warning: %s is already being visited by a buffer, contents will be overwritten! Entering edebug" my-data-save-file))
(edebug))
This will warn you and then enter the debugger if a file you are visiting in some buffer is about to be overwritten by your macro, where you can inspect what is going on.
Here is part the docstring of find-file-no-select:
Read file FILENAME into a buffer and return the buffer.
If a buffer exists visiting FILENAME, return that one, but
verify that the file has not changed since visited or saved.
My guess is that the my-data-save-file is already being visited by a buffer, so that is the buffer that is returned (and subsequently overwritten). But you can really find out what is happening with (edebug).
Just a quick reply to some of what you said. Your message never appears probably because you test whether the buffer of with-current-buffer is the current-buffer, which it always is, unless body changes the current buffer.
But you are right to use with-current-buffer instead of save-excursion followed by set-buffer.
As for other ways: why not put your data in a temporary buffer and then use write-file or append-to-fileor write-region?
FWIW, I tried your code briefly and saw no problem. But I just tried a simple (prin1 (symbol-function 'my-save-some-data)) for the body and a constant file name for the file. I tried with pre-existing file or not, and with pre-existing buffer or not, and with pre-existing unsaved modified buffer or not.
Are you testing with the interpreted code (e.g., macro present) or byte-compiled code?

org-mode capture with sexp

I'm trying to get create a capture template that converts an URL to an org-mode link with the <title> as the link name.
My conversion function looks like this:
(defun get-page-title (url)
"Get title of web page, whose url can be found in the current line"
;; Get title of web page, with the help of functions in url.el
(with-current-buffer (url-retrieve-synchronously url)
;; find title by grep the html code
(goto-char 0)
(re-search-forward "<title>\\([^<]*\\)</title>" nil t 1)
(setq web_title_str (match-string 1))
;; find charset by grep the html code
(goto-char 0)
;; find the charset, assume utf-8 otherwise
(if (re-search-forward "charset=\\([-0-9a-zA-Z]*\\)" nil t 1)
(setq coding_charset (downcase (match-string 1)))
(setq coding_charset "utf-8")
;; decode the string of title.
(setq web_title_str (decode-coding-string web_title_str (intern
coding_charset)))
)
(concat "[[" url "][" web_title_str "]]")
))
When called from normal emacs lisp code it returns the correct result. But when used in this org-capture-template it only returns bad url.
setq org-capture-templates
(quote
(("l" "Link" entry (file+headline "" "Links")
"* \"%c\" %(get-page-title \"%c\")"))))
Is the order of expansion different? Do I need to escape the string differently? Magic?
The first %c is only their to debug the string and indeed is getting printed as "url".
Please don't even bother pointing out that parsing XML with regexp is the wrong approach. Cthulhu is already haunting me and this isn't going to make it worse.
The problem is the order of expansion of template parameters. The simple % templates are expanded after the sexp has been evaluated. The original error message still contains a template and thus is expanded into the contents of the clipboard and thus the error message contains not the string that was originally passed to get-page-title.
The solution is to access the kill ring from within the sexp:
%(get-page-title (current-kill 0))
EDIT This behavior is now documented in org-mode.
Wouldn't the solution be to use org-protocol.el?
http://orgmode.org/worg/org-contrib/org-protocol.html
I just tested it with the following template (adding a sub-heading for your desired title as headline).
Template:
("t"
"Testing Template"
entry
(file+headline "~/org/capture.org" "Testing")
"* %^{Title}\n** %:description\n\n Source: %u, %c\n\n%i"
:empty-lines 1)
Then using a browser-based keybind (in my case with Opera, although examples for Firefox, Uzbl, Acrobat and Conkeror are provided as well) I was able to capture the following:
** Testing for StackExchange
*** org-protocol.el - Intercept calls from emacsclient to trigger custom actions
Source: [2011-08-05 Fri], [[http://orgmode.org/worg/org-contrib/org-protocol.html]
[org-protocol.el - Intercept calls from emacsclient to trigger custom actions]]
org-protocol intercepts calls from emacsclient to trigger custom actions
without external dependencies.
(I broke the org-link simply to keep the scrolling to a minimum, it was not on two lines originally)
#aboabo shared an undocumented variable in https://stackoverflow.com/a/21080770/255961 that provides a more general solution to the question's topic of how to use sexp with keyword values in a template (beyond kill ring). The variable org-store-link-plist stores all the information being passed to the capture. So you can access its values directly from a function like this:
(defun url()
(plist-get org-store-link-plist :url))
("w" "capture" entry (file "~/refile.org")
"* [[%:link][%:description]] :NOTE:\n%(url)%U\n"
:immediate-finish t)
PS, According to the manual page (quote below) it sounds to me like your approach in teh question should work also. But I agree what you describe is what seems to be actually happening - it seems like a bug relative to the manual.
%(sexp) Evaluate Elisp sexp and replace with the result. For convenience,
%:keyword (see below) placeholders within the expression will be
expanded prior to this.

How can I set a default path for interactive directory selection to start with in a elisp defun?

I want a function to interactively prompt for an existing directory, but instead of starting from default-directory, I would like a function local default path like '~/should/start/here/always/in/this/function' to start at when using (interactive "D") how can I achieve this? My first thought is to create another function which first sets default-dir and then calls my original function, but that doesn't seem right, and I am unsure of how interactive would be prompted in that case.
Since you're writing this yourself, you can do something like this:
(defun choose-directory (directory)
"sample that uses interactive to get a directory"
(interactive (list (read-directory-name "What directory? "
choose-directory-default-directory)))
(message "You chose %s." directory))
(defvar choose-directory-default-directory "/home/tjackson/work/data"
"Initial starting point.")
Which uses interactive with a lisp expression to call read-directory to get a directory name (you might want to add additional arguments, check the link/docs).
Your original hunch would work as well, though, as you thought, isn't quite as clean. But, it does work well when you don't want to, or cannot, modify the function whose behavior you want to change. I've included that solution below to show you how you'd achieve it (the only piece of the puzzle you didn't mention was call-interactively):
;; original version of choose-directory, calling (interactive "D")
(defun choose-directory (directory)
"sample that uses interactive to get a directory"
(interactive "DWhat directory? ")
(message "You chose %s." directory))
(defun wrap-choose-directory ()
(interactive)
(let ((default-directory choose-directory-default-directory))
(call-interactively 'choose-directory)))