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-link
does 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-c
and function keys to F5
onward 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
init.el
:
(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-link
that has our basic
functionality, but by default it prompts the user twice, which I think
is unnecessary. Fortunately, the method takes a LINK-LOCATION
and
DEFAULT-DESCRIPTION
as 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-link
has 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-map
is the one to use by
just running M-x apropos
on the regex org.*map
. In general, any
mode will have a map, and the pattern is usually -mode-map
,
where
can be whatever mode you interested in adding to.
I'll add this code to my large
eval-after-load
form 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
with suffix
-mode-map
. - Use the user-space keybindings, those starting with
C-c
, and the function keysF5
on up.
No comments:
Post a Comment