Emacs Dired “Shortcuts”

4

I’m always trying to make my development workflow more efficient – whether it be tools or process – and this post solved one of my recent pain points – as well as giving me another practical problem to solve with Lisp.

As I noted previously, I’m really heavy into Emacs use at the moment: development, calendaring, RSS, news, Jabber IM – all from within this awesome thing called Emacs.

As I started to use it more and more for all types of different chores – and more specific to this post – file editing, I began to notice fairly quickly that directory navigation with Dired (Ctrl-X d, by default) led to far too many keystrokes to get to disparate locations – and to boot there was no notion of persistent “favorites” or “shortcuts”.

The above may just be my newness to the Emacs ecosystem and the functionality may actually exist – but it never turned up in my many searches. So I went about providing my own solution.

NOTE: This effort had no intention of making handy-dandy menu items as I don’t like them – or the mouse for that matter – all that much. Maybe I’ll add that at some point for thoroughness sake – we’ll see.

The plan was simple:

  1. Create a dictionary of shortcut to locations
  2. Use Emacs interactive ability to select a shortcut name and open its location with Dired.

The dictionary was easy once I got familiar with the alist syntax:

1
("dev_seamonkey" . "g:/code/projects/my-projects-pre-change/seamonkey")

Now to just add a list of those guys (one for each shortcut) to my shorcuts alist.

1
2
3
(setq my-shortcuts-alist '(
 ("dev_seamonkey" . "g:/code/projects/my-projects-pre-change/seamonkey")
 ("dev_legacy" . "g:/code/projects/my-projects-pre-change/my-projects"))

Cool, simple enough. Now, how do I get the keys out of this guy to be used with Emacs interactive? I searched around a bit and found a decent snippet that I modified for my purposes.

1
2
3
(interactive
 (list
 (completing-read "Choose shortcut: " (mapcar '(lambda (arg) (car arg)) my-shortcuts-alist))))

Ok, so that guy is quite a bit more confusing – here’s the gist:

  • mapcar is a form that takes a function and a list, to which it applies the supplied function to each list member
  • Remember our alist is a list of lists – so mapcar sends each list as the arg to lambda
  • lambda returns the car (first item) of the arg (a list) – meaning it returns the key for each of our lists
  • completing-read assembles them into a list to return to interactive.

Voila – Emacs interactive now has a list of defined shortcuts from which it will let the user choose – awesome!

After that, the last part was simple (well it was after I figured out how to pull a list out of the alist by key)

1
 (cdr(assoc shortcut my-shortcuts-alist))

Again, this is pretty simple once you know what functions to use to do the task at hand.

  • assoc takes a string and an alist and will return the list with the first element matching the key, or nil
  • We then cdr that list (get the last element) – which is the actual location
  • The dired command then uses that value to open your desired directory location

Awesome!

Full Codedired_util.el

Tags: , , ,

4 Comments

SomeoneElse
Mar 13, 2013 at 8:20 am

You can simplify your completing function like that:

(interactive
(list
(completing-read "Choose shortcut: " (mapcar 'car my-shortcuts-alist))))


 
Jake
Mar 13, 2013 at 9:42 am

This is one of the reasons I have this blog – thank you for that. Not sure why I didn’t see that myself!


 
Warren Wilkinson
Aug 1, 2013 at 1:23 pm

You might also try emacs bookmarks.

1. Go visit your directory in dired.
2. Bookmark it (C-x r m)
You’ll get to give it a name.
3. Jump back later (C-x r b)
(and it’ll prompt you for the name)

You can also bookmark important files, info docs, etc. You make remove bookmarks with the bookmark editor (C-x r l). Press d to mark a bookmark for deletion, x to perform deletions.


 
Jake
Aug 1, 2013 at 1:52 pm

Great suggestion!

Yet another reason Emacs is awesome – there are so many ways to accomplish your goal!

For me, the method I presented gave me a great learning opportunity – but your suggestion I’m sure is much more full featured :)


 

Reply

%d bloggers like this: