I've been wanting to create a function for a while that easily lets me store and paste links to an org-mode file. Org already supports this, so this should be quite easy.
I'd like to bind a key to store a link to the present point. The function
org-store-linkdoes this, so all we need is a keybinding for this, since one doesn't exist by default. We do this with the function
global-set-key. But we have to choose a key sequence first. If you want a great guide on keybinding, the awesome blog Mastering Emacs has a wonderful writeup. So, as the Mastering Emacs blog notes, all keys starting with
C-cand function keys to
F5onward are available for user binding. For some reason I don't understand, org-mode takes many of these bindings for itself. So, we should check what's already bround, so I need to take a look at all currently keybindings
C-h b. Looking at my keybindings, I see I don't have any bindings for
C-c g, so let's use that. I'll add the following in my
(define-key global-map (kbd "C-c g") 'org-store-link)
The next part is to write a small function to add the link in an org file. There's a function already
org-insert-linkthat has our basic functionality, but by default it prompts the user twice, which I think is unnecessary. Fortunately, the method takes a
DEFAULT-DESCRIPTIONas optional arguments, so we shouldn't have to do much work. Here's what the method looks like:
(defun ash/org-link-description (link) "Makes a useful description from a link." (cond ((string-match "^file:" link) (file-name-nondirectory link)) (t nil))) (defun ash/org-paste-link () "Paste all stored links without prompting." (interactive) (unwind-protect (flet ((read-string (prompt &optional initial-input history default-value inherit-input-method) initial-input)) (dolist (link (delete-duplicates org-stored-links :test 'equal)) (org-insert-link nil (car link) (ash/org-link-description (car link))))) (setq org-stored-links nil))) (define-key org-mode-map (kbd "C-c p") 'ash/org-paste-link)
The definition of
ash/org-paste-linkhas a few interesting features, but what I really want to talk about is keybindings, so I won't explain why I had to do things the way I did. I may get into writing new commands in a later post.
The interesting part for keybindings here is that I bound it to
org-mode-map. That means this binding will only be in effect in org-mode buffers. I found that
org-mode-mapis the one to use by just running
M-x aproposon the regex
org.*map. In general, any mode will have a map, and the pattern is usually
can be whatever mode you interested in adding to.
I'll add this code to my large
eval-after-loadform for org-mode, so that it will only evaluated once I start using org-mode. This might be a bad idea if I want to grab a link before I visit an org-mode file for the first time, since my keybinding will not be loaded at that point. I'll have to see if that is something I'm liable to do, and if so, I'll move that keybinding out.
The lessons here are:
- Use keybindings for common tasks.
- Use global keybindings for things you might want to do in any buffer.
- For things you only want to do depending on the mode, use the
mode specific keybinding, which can be found at the package map
- Use the user-space keybindings, those starting with
C-c, and the function keys