0

Emacs' Bookmarks are great, as is navigating the list of buffers. But I find it nice to have shorter chords to get directly to where I want to go. So I have been accruing a repetitive set of functions and keybindings for all my favorite files and folders.

I wondered if I could use a dolist to handle this repetitiveness, but am no good programmer.

Here is one of the (seven and rising) repetitively defined functions, and a feeble attempt at writing the dolist following:

(defun jump-to-main ()
  (interactive)
  (find-file main))
(global-set-key (kbd "C-c m") 'jump-to-main)

This might barely qualify as pseudocode:

(dolist (x '(("m" main)
             ("t" tech))
           (defun (concat 'jump-to- (cdr x)) ()
             (interactive)
             (find-file (cdr x)))
           (global-set-key (kbd (concat "C-c " (car x))) 
                           '(concat 'jump-to- (cdr x)))
           ))

The payoff in an elegant init file, versus how fast I am at solving at Lisp problems... hoping the Stackoverflow can save me.

Other strategies and approaches are appreciated.

EDIT:

With lawlist's suggestion, my question may reduce and be more clear presented the following way. I would like to reduce the repetition in the following series of keybindings.

(global-set-key (kbd "C-c A") 
                (lambda () 
                  (interactive) 
                  (find-file fileA)))

(global-set-key (kbd "C-c B") 
                (lambda () 
                  (interactive) 
                  (find-file fileB)))

...

(global-set-key (kbd "C-c Z") 
                (lambda () 
                  (interactive) 
                  (find-file fileZ)))

fileK for example expands to something like "~/fileK.txt".

EDIT:

So here is another try:

(dolist (x '(("m" main)
             ("t" tech))
           (global-set-key (kbd (concat "C-c " (car x)))           
                           (lambda ()
                             (interactive)
                             (find-file (cdr x))
                             ))))

The keybinding part seems okay, but (find-file (cdr x)) isn't doing what I need, and I couldn't fix it in a small amount of googling lisp.

Here are the expressions I'm using to focus on the broken parts:

(setq somefile "~/somefile.txt")
(setq x '("s" . somefile))
(concat "C-c " (car x))
(find-file (cdr x))

The last line is the one that doesn't work, as (cdr x) apparently evaluates to (main). I tried slipping in an eval to expand the main variable, but it doesn't seem...

Reading Phil's answer now, this may take me a while.

Brady Trainor
  • 2,026
  • 20
  • 18
  • Where is `main` located? Where is `tech` located? I'm confused . . . Are they files or directories? Are you trying to open a dired-mode buffer or a file visiting buffer? Something like this? `(global-set-key (kbd "C-c m") (lambda () (interactive) (dired "/Volumes")))` – lawlist Jun 29 '14 at 01:36
  • @lawlist, `main` and `tech` are variables for filenames. I'm using variables so that I can move files around on a whim, and it won't break my Emacs' workflow. By the way, I can use `find-file` uniformly as it will open `dired` for directories. – Brady Trainor Jun 29 '14 at 01:41
  • How about? `(global-set-key (kbd "C-c m") (lambda () (interactive) (find-file main)))` and `(global-set-key (kbd "C-c t") (lambda () (interactive) (find-file tech)))` – lawlist Jun 29 '14 at 01:43
  • @lawlist, That only combines each pair of functions, and to the detriment, if I want to view keybindings, would get `?` instead of a name of a function. But, what I'm more worried about, is that I have seven functions that look exactly the same, and it gets larger. I will edit the question to make it more clear where my unwanted repetition is... Ah, but if using the lambda makes it easier to construct the dolist, then that would take precedence. – Brady Trainor Jun 29 '14 at 01:48
  • I think you are already doing it correctly (**without** the `dolist` / `car` / `cdr` / `concat` / etc.), and if you want a pretty describe key readout in your buffer, then your first example is also good -- i.e., `defun jump-to-main . . .` – lawlist Jun 29 '14 at 02:02
  • 1
    How about a fancy function with choices? One keyboard shortcut and then several choices -- 1 2 3 4 or a b c d e? Like these -- there are four (4) ideas in that link?: http://stackoverflow.com/a/19284395/2112489 I've also recently updated my context menu example, if that type of option interests you . . . here is the context menu update that differs from the one in the previous link: http://stackoverflow.com/a/24346990/2112489 – lawlist Jun 29 '14 at 02:06
  • Your last `dolist` form should work at one condition: you put your Elisp file in `lexical-binding` mode (i.e. add `-*- lexical-binding:t -*-` somewhere on its first line). – Stefan Jun 30 '14 at 14:13

1 Answers1

1

FWIW, a fairly direct translation of your pseudo-code is:

(defvar my-file-main (expand-file-name "~/main") "My main file")
(defvar my-file-tech (expand-file-name "~/tech") "My tech file")

(dolist (x '(("m" . my-file-main)
             ("t" . my-file-tech)))
  (let* ((sym (cdr x))
         (func (intern (concat "jump-to-" (symbol-name sym)))))
    (defalias func `(lambda ()
                      ,(format "Jump to file `%s'." (symbol-name sym))
                      (interactive)
                      (find-file ,sym)))
    (global-set-key (kbd (concat "C-c " (car x))) func)))
phils
  • 71,335
  • 11
  • 153
  • 198