1

I'm using the following solution to quickly open files in Emacs (thanks to lawlist for the code)

The code : OPTION # 2 -- function with options:

(global-set-key (kbd "<f5>") 'lawlist-bookmark)

(defun lawlist-bookmark (choice)
  "Choices for directories and files."
  (interactive "c[D]ired | [v]ocab.org | [g]td.org | [d]iary.org | [n]otes.org")
    (cond
           ((eq choice ?D)
           (dired "/very/long/and/boring/path/which/make/me/use/tab/for/..."))
           ((eq choice ?v)
           (find-file "/Users/HOME/.0.data/vocab.org")
            (message "Opened:  %s" (buffer-name)))
          ((eq choice ?g)
           (find-file "/Users/HOME/.0.data/gtd.org")
            (message "Opened:  %s" (buffer-name)))
          ((eq choice ?d)
           (find-file "/Users/HOME/.0.data/diary.org")
            (message "Opened:  %s" (buffer-name)))
          ((eq choice ?n)
           (find-file "/Users/HOME/.0.data/notes.org")
            (message "Opened:  %s" (buffer-name)))
          (t (message "Quit"))))

It works well. I press F5 and then another key to open my file. However, I have now a lot of shorcuts and I would like to call them by pressing two (or more) keys.

For example, I have a project named "website-kate" which is a folder containing two main files index.html and stylesheet.css. I would like two shortcuts ki (that is to say: press F5 to open shorcut dial and press first k and then i for "kate" and "index") and ks (for "kate" and "stylesheet")

Of course this code doesn't work:

    ((eq choice ?ki)
    (find-file "/home/user/website-kate/index.html")
        (message "Opened:  %s" (buffer-name)))
Community
  • 1
  • 1
ppr
  • 685
  • 7
  • 24
  • Your existing solution suffers from severe mixing of code and data. I would suggest you seriously consider moving to options #3 in the linked question as your collection of bookmarked files continues to grow. (It seems to be hard-wired for mouse usage but proper keymaps is the way to go for keyboard support, too.) – tripleee Aug 20 '14 at 15:48
  • @tripleee I didn't choose option #3 because I don't like using the mouse. If there is a simple way to adapt option #3 to keyboard shorcut, I'm interested. I tried to replace mouse indication by keyboard one but I didn't get a working code... – ppr Aug 20 '14 at 16:11
  • 2
    Such an approach does not scale well. And updating locations that might change is tedious. Why don't you just use Emacs bookmarks? That's what they're for. You can have a single-press key such as `F5` to prompt for a bookmark, and one or more chars for the bookmark name: `F5 k i RET`. – Drew Aug 20 '14 at 18:06
  • I second @Drew's suggestion. Implementing highly specialized solutions that suit your work-flow can be very rewarding, but sometimes it makes sense to take a step back and look at what Emacs offers out of the box to support the use case you are trying to address. I suggest you start by reading the `*info*` node about Emacs bookmarks: `C-h r m Bookmarks RET`. If you don't want to do that for some reason, the TLDR; is: – itsjeyd Aug 21 '14 at 06:33
  • `C-x r m` to set a bookmark for the current file/directory (records position of point as well!), `C-x r b` to jump to a bookmark, and `C-x r l` to get a list of bookmarks currently defined. If you don't like these key bindings, you can of course customize them to your heart's content: `C-x r b` runs `bookmark-jump`; based on your existing code you would probably want to bind that command to `F5`. – itsjeyd Aug 21 '14 at 06:35
  • 1
    @itsjeyd (and Drew) thanks, I will explore the bookmark possibility. – ppr Aug 21 '14 at 10:38

1 Answers1

1

The interactive form using strings can only read a single key, but interactive can also take a form to evaluate instead of a string, so you can implement your own multi-key reading form. For example like this:

(interactive
 (list
  (let ((key (read-key "First key: ")))
    (cond
     ((equal key ?a)
      (message "a pressed"))
     ((equal key ?k)
      (let ((key (read-key "Second key: ")))
        (cond
         ((equal key ?i)
          (message "ki pressed"))
         (t
          (message "I don't know k%c" key)))))))))

This should be easy to extend to your full use case. (Doing it in a way that is easy to configure is slightly harder, though.)

Internally, (interactive "cFoo: ") does simply use read-key, so you're just expanding on the same concept.

Jorgen Schäfer
  • 1,196
  • 6
  • 8
  • Is it possible to use this solution in parallel with the former one? – ppr Aug 20 '14 at 15:39
  • You will have to return something else than "single character" from the interactive spec (e.g. symbols would work). Alternatively, you can skip the interactive spec entirely and do the user query from the function body. That would make the function unusable from lisp, but I don't think that's a problem. Do you want a full example for either of these? – Jorgen Schäfer Aug 20 '14 at 17:51