How can I load an Emacs capture template into an open file? - emacs

Please excuse my newness to Emacs Lisp. I started using org-mode and love it. In my workflow, I am trying to load a template into an open buffer or prompt the template to ask for a location to where the file is to be saved.
For example, I have a 'meetings' template. When I call that template, I would like to be prompted for a filename and then the template will be loaded into that file and file will be loaded in Emacs.
How can I do this within Emacs?

This is the best I could come up with so far:
(defun caputre-create-meeting-link ()
(let ((new-file (read-file-name "Save meeting info in ")))
(run-with-timer 1 nil (eval `(lambda () (find-file ,new-file))))
(format "[[%s]]" new-file)))
(setq org-capture-templates
'(("a" "Insert a link to meeting" plain
(file "~/org/notes.org")
"Meeting info: %(caputre-create-meeting-link)"
:immediate-finish t)))
to more or less get the effect you describe. But you probably could simply substitute %(capture-create-meeting-link) with %^L and then C-c C-o on the link to open it.

Related

Jump to zotero from emacs failed

I'd like to jump to zotero when I click zotero links like zotero://select/items/1_2S5A64QI in my org file, but at the first time it doesn't work (no response). After opened the .emacs file and M-x RET eval-buffer RET, I backed to the org file, this time I can jump to the zotero successfully. What cause it?
(defun zotero-org (path)
(browse-url (format "zotero:%s" path)))
(org-add-link-type "zotero" 'zotero-org)
This is what I use to add a new link type.
You need to add-link after org is loaded.
Besides, org-add-link-type is obsolete since 9.0; use org-link-set-parameters instead.
(defun org-zotero-open (path)
(browse-url (format "zotero:%s" path)))
(with-eval-after-load 'org
(org-link-set-parameters "zotero" :follow #'org-zotero-open))

How to configure Emacs to archive Done tasks to archive file?

I keep all tasks in a todo.org file. After a task is done, I'd like to select and archive it to a separate archive.org file. I want to set this up in my config file, of course, not as a per-file header.
I tried this:
(setq org-archive-location (concat org-directory "~/Dropbox/logs/archive.org::"))
Which seems to work; I see a message that the task has been archived to my chosen path. But--when I open archive.org, nothing is there. Ever. Then, whenever I close and reopen Emacs, I see the error message Symbol's value as variable is void: org-directory.
So: How do I properly configure Emacs to archive tasks I choose to the correct place? Still an Org mode neophyte, so have mercy.
EDIT: Using Emacs 25.3.2, and Org 9.1.7.
Inasmuch as the O.P. has also expressed (in a comment underneath the original question) a desire to automatically save the target archive buffer, this answer addresses that as well:
(require 'org)
(setq org-archive-location "~/Dropbox/logs/archive.org::")
(defun org-archive-save-buffer ()
(let ((afile (org-extract-archive-file (org-get-local-archive-location))))
(if (file-exists-p afile)
(let ((buffer (find-file-noselect afile)))
(if (y-or-n-p (format "Save (%s)" buffer))
(with-current-buffer buffer
(save-buffer))
(message "You expressly chose _not_ to save (%s)" buffer)))
(message "Ooops ... (%s) does not exist." afile))))
(add-hook 'org-archive-hook 'org-archive-save-buffer)

How to export org file to HTML file when save?

I want to export my org files to HTML files to certain directory when save.
I can use Emacs and Org-mode but I don't know Elisp.
With Org-Mode 8.3 and Emacs 24.5.1 the accepted answer creates a pseudo-buffer *Org HTML Export* that you have to save manually, while the key C-c C-e h h more conveniently saves the file directly.
To really auto-export in the background try the following code:
# Local variables:
# eval: (add-hook 'after-save-hook 'org-html-export-to-html t t)
# end:
You can combine this solution with the following function in your .emacs:
(defun toggle-html-export-on-save ()
"Enable or disable export HTML when saving current buffer."
(interactive)
(when (not (eq major-mode 'org-mode))
(error "Not an org-mode file!"))
(if (memq 'org-html-export-to-html after-save-hook)
(progn (remove-hook 'after-save-hook 'org-html-export-to-html t)
(message "Disabled org html export on save"))
(add-hook 'after-save-hook 'org-html-export-to-html nil t)
(set-buffer-modified-p t)
(message "Enabled org html export on save")))
Note: The below was written for Emacs 23. Check the answer by #AndreasSpindler for an up-to-date solution.
Emacs has a couple of hooks which are called in certain events. The hook you are looking for is probably the after-save-hook. Just set it to the function you want to run every time you save the file. In your case this would be org-html-export-to-html.
There are many ways to do this, but the following method is probably the fastest and doesn't involve any "real" elisp. Put the following lines somewhere in your org file:
# Local variables:
# after-save-hook: org-html-export-to-html
# end:
The next time you open that file, you'll get a warning and be asked if the local variable should be set (as that's potentially unsafe, but not a problem here). Press y and everything should just work.
The command for this is
C-c C-e h h (org-html-export-to-html)
Export as an HTML file. For an Org file myfile.org, the HTML file will be myfile.html. The file will be overwritten without warning. C-c C-e h o Export as an HTML file and immediately open it with a browser.
Reference

Emacs org-mode: textual reference to a file:line

I am using org-mode in Emacs to document my development activities. One of the tasks which I must continuously do by hand is to describe areas of code. Emacs has a very nice Bookmark List: create a bookmark with CTRL-x r m, list them with CTRL-x r l. This is very useful, but is not quite what I need.
Org-mode has the concept of link, and the command org-store-link will record a link to the current position in any file, which can be pasted to the org-file. The problem with this is two-fold:
It is stored as an org-link, and the linked position is not directly visible (just the description).
It is stored in the format file/search, which is not what I want.
I need to have the bookmark in textual form, so that I can copy paste it into org-mode, end edit it if needed, with a simple format like this:
absolute-file-path:line
And this must be obtained from the current point position. The workflow would be as simple as:
Go to the position which I want to record
Call a function: position-to-kill-ring (I would bind this to a keyboard shortcut)
Go to the org-mode buffer.
Yank the position.
Edit if needed (sometimes I need to change absolute paths by relative paths, since my code is in a different location in different machines)
Unfortunately my lisp is non-existent, so I do not know how to do this. Is there a simple solution to my problem?
(defun position-to-kill-ring ()
"Copy to the kill ring a string in the format \"file-name:line-number\"
for the current buffer's file name, and the line number at point."
(interactive)
(kill-new
(format "%s:%d" (buffer-file-name) (save-restriction
(widen) (line-number-at-pos)))))
You want to use the org-create-file-search-functions and org-execute-file-search-functions hooks.
For example, if you need the search you describe for text-mode files, use this:
(add-hook 'org-create-file-search-functions
'(lambda ()
(when (eq major-mode 'text-mode)
(number-to-string (line-number-at-pos)))))
(add-hook 'org-execute-file-search-functions
'(lambda (search-string)
(when (eq major-mode 'text-mode)
(goto-line (string-to-number search-string)))))
Then M-x org-store-link RET will do the right thing (store a line number as the search string) and C-c C-o (i.e. M-x org-open-at-point RET) will open the file and go to this line number.
You can of course check for other modes and/or conditions.
An elisp beginner myself I though of it as a good exercise et voila:
Edit: Rewrote it using the format methode, but I still think not storing it to the kill-ring is less intrusive in my workflow (don't know about you). Also I have added the capability to add column position.
(defvar current-file-reference "" "Global variable to store the current file reference")
(defun store-file-line-and-col ()
"Stores the current file, line and column point is at in a string in format \"file-name:line-number-column-number\". Insert the string using \"insert-file-reference\"."
(interactive)
(setq current-file-reference (format "%s:%d:%d" (buffer-file-name) (line-number-at-pos) (current-column))))
(defun store-file-and-line ()
"Stores the current file and line oint is at in a string in format \"file-name:line-number\". Insert the string using \"insert-file-reference\"."
(interactive)
(setq current-file-reference (format "%s:%d" (buffer-file-name) (line-number-at-pos))))
(defun insert-file-reference ()
"Inserts the value stored for current-file-reference at point."
(interactive)
(if (string= "" current-file-reference)
(message "No current file/line/column set!")
(insert current-file-reference)))
Not tested extensively but working for me. Just hit store-file-and-line or store-file-line-and-col to store current location and insert-file-reference to insert the stored value at point.
BTW, if you want something better than FILE:LINE, you can try to use add-log-current-defun (in add-log.el) which should return the name of the current function.
;; Insert a org link to the function in the next window
(defun insert-org-link-to-func ()
(interactive)
(insert (with-current-buffer (window-buffer (next-window))
(org-make-link-string
(concat "file:" (buffer-file-name)
"::" (number-to-string (line-number-at-pos)))
(which-function)
))))
This func generates link with the function name as the description.
Open two windows, one is the org file and the other is src code.
Then M-x insert-org-link-to-func RET

emacs - save current buffer list to a text file

Quite often I need to get a simple text copy of my currently opened files. The reasons are usually:
I want to send the list to a colleague
I want to document whatever I am working on (usually in an org document)
I want to act on one of my currently opened files, on the shell. I need to copy-paste the pathname for that.
The fact is that the usual buffer-menu or list-buffers provide a convenient menu to navigate the opened buffers, but are very inconvenient to copy-paste to the the terminal the names of the opened files, or to perform any of the actions mentioned above. For example: I can not double-click in a line to select the full path-name, and I can not use the kill/yank emacs sequence to copy around the path-name.
Summary: I would like a way to export to a text file (or to a new buffer) the list of opened files, without other data; no file size, mode, or any other emacs metadata.
Is there a command for that? An extra package I can install?
EDIT
Adding solution by Trey Jackson, modified to provide some feedback of what has been done:
(defun copy-open-files ()
"Add paths to all open files to kill ring"
(interactive)
(kill-new (mapconcat 'identity
(delq nil (mapcar 'buffer-file-name (buffer-list)))
"\n"))
(message "List of files copied to kill ring"))
This command will do the job for you:
(defun copy-open-files ()
"Add paths to all open files to kill ring"
(interactive)
(kill-new (mapconcat 'identity
(delq nil (mapcar 'buffer-file-name (buffer-list)))
"\n")))
You can change the mode of your *Buffer List* buffer. By default, it will be in mode Buffer Menu, but changing it to text-mode or fundamental-mode will remove all the special behavior allowing you to cut and paste from it just like a regular buffer. The metadata can easily be chopped off with delete-rectangle.
Alternatively, you can access the buffer list programmatically with elisp:
(dolist (buffer (buffer-list))
(when (buffer-file-name buffer)
(insert (buffer-file-name buffer) "\n")))
You certainly should be able to copy and yank from the buffer list.
e.g. copy everything with C-xhM-w and then yank into a new buffer for editing.