سؤال

I have a very complex and dense structure of folders and files. I would like to open a file which is very far away from my home quickly in emacs.

C-x C-f is not quick enough because I have to write the path which could be very long (example : /very/long/and/boring/path/which/make/me/use/tab/for/autocompletion/too/much/and/ruins/my/hands/with/repetitive/strain/injuries/my_file_finally.tex)

So, is it another way, quicker, (than C-x C-f) to open such file and, if not, is there a way to create shortcuts for the most used files ?

P-S : I don't want to move files (long paths means to me clean and organized computer).

هل كانت مفيدة؟

المحلول 2

OPTION # 1 -- one function per assigned key:

(global-set-key (kbd "<f6>") (lambda () (interactive)
  (find-file "/Users/HOME/.0.data/todo.org")
  (message "Opened:  %s" (buffer-name))))

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"))))

OPTION # 3 -- right click context menu (popup):

(global-set-key [mouse-3] 'lawlist-popup-context-menu)

(defvar lawlist-context-menu-map
  (let ((map (make-sparse-keymap "Context Menu")))
    (define-key map [find-file-todo] (cons "ToDo" (lambda () (interactive)
      (find-file "/Users/HOME/.0.data/todo.org"))))
    (define-key map [find-file-gtd] (cons "GTD" (lambda () (interactive)
      (find-file "/Users/HOME/.0.data/gtd.org"))))
    (define-key map [find-file-notes] (cons "Notes" (lambda () (interactive)
      (find-file "/Users/HOME/.0.data/notes.org"))))
    (define-key map [find-file-vocab] (cons "Vocab" (lambda () (interactive)
      (find-file "/Users/HOME/.0.data/vocab.org"))))
    (define-key map [find-file-diary] (cons "Diary" (lambda () (interactive)
      (find-file "/Users/HOME/.0.data/diary.org"))))
    (define-key map [seperator-three] '(menu-item "--"))
    (define-key map [help-for-help] (cons "Help" 'help-for-help))
    (define-key map [seperator-two] '(menu-item "--"))
    (define-key map [my-menu] (cons "LAWLIST" (make-sparse-keymap "My Menu")))
    (define-key map [my-menu 01] (cons "Next Line" 'next-line))
    (define-key map [my-menu 02] (cons "Previous Line" 'previous-line))
    (define-key map [seperator-one] '(menu-item "--"))
  map) "Keymap for the LAWLIST context menu.")

(defun lawlist-popup-context-menu  (event &optional prefix)
  "Popup a context menu."
  (interactive "@e \nP")
    (define-key lawlist-context-menu-map [lawlist-major-mode-menu]
      `(menu-item ,(symbol-name major-mode)
        ,(mouse-menu-major-mode-map) :visible t))
    (popup-menu lawlist-context-menu-map event prefix))

OPTION # 4 -- menubar drop-down menu:

(require 'easymenu)

(easy-menu-define lawlist-menu global-map "My own menu"
  '("lawlist"
    ["Next Line" next-line t]
    ["Previous Line" previous-line t]
    ["Dired Mode" dired t]
    ["--" my-function t]
    ("Favorites"
    ["Diary" (find-file "/Users/HOME/.0.data/diary.org")]
    ["--" diary]
    ["GTD" (find-file "/Users/HOME/.0.data/gtd.org")]
    ["--" gtd]
    ["Vocab" (find-file "/Users/HOME/.0.data/vocab.org")]
    ["--" vocab]
    ["Notes" (find-file "/Users/HOME/.0.data/notes.org")]
    ["--" notes]
    ["ToDo" (find-file "/Users/HOME/.0.data/todo.org")]
    )  ))

نصائح أخرى

In addition to the above answers, helm may be a good solution to your problem. While it does less than icicles in the realm of sophistocated pattern matching and creating/managing/saving complex sets of files, helm does what it does both well and fast (both from a keystrokes perspective and software/latency perspective). Just M-x package-install <ret> helm <ret> and you're set.

First, helm can track recenf, a list of the files that you have used recently. Just M-x helm-recentf and type a string/regex that will be matched to the file name you want, it will match it to filenames you have opened recently in real time. Scroll and enter to select the one.

But wait! There's more: (Sorry if this is starting to sound like an advertisement) If you're on Linux (I'll assume that since you use slashes in your paths and it seems that the emacs+linux > mac+linux), you can use GNU locate, a tool for finding files anywhere on your system as long as the locate daemon has seen it before, which it probably has if the file has been around for any amount of time (see below for when it it hasn't). It's practically real time. The locate process is fast and helm streams the results in real time. The command for that is M-x helm-locate.

Now, what if you want to find files in git/mercurial/bazaar/etc. projects? You can use projectile, a "project interaction library". With helm-projectile (you'll need both projectile and helm-projectile installed the same way you did helm itself). It will stream file/directory names and anything else into helm. Once again. All you need is to type a substring that matches anywhere, and helm will find it for you. M-x helm-projectile

It's Github README says "helm is capable of a lot". There is much, much more to helm. Try helm-moccur, helm-ack (external package), helm-imenu, helm-browse-code, helm-tracker-search, helm-dabbrev etc. etc. etc.

And finally: why choose one? One thing that helm does really well is creating you own commands. Here's a function that searches all of the above.

;; you'll need to require helm-config and helm-projectile somewhere above
(defun my-helm-omni (&rest arg) 
  ;; just in case someone decides to pass an argument, helm-omni won't fail.
  (interactive)
  (helm-other-buffer
    (append '(helm-c-source-buffers-list ;; list of all open buffers
               helm-c-source-recentf)    ;; all recent files

      ;; projectile errors out if you're not in a project 
      (if (projectile-project-p) ;; so look before you leap
        '(helm-source-projectile-files-list
           helm-source-projectile-recentf-list
           helm-source-projectile-buffers-list)
        '())

      '(
         helm-c-source-files-in-current-dir ;; files in current directory
         helm-c-source-locate               ;; file anywhere
         helm-c-source-bookmarks            ;; bookmarks too
         helm-c-source-buffer-not-found     ;; ask to create a buffer otherwise
         ))
    "*helm-omni*"))

I have this bound to C-c o

  1. See this answer to almost the same question. In particular, consider using (a) Dired bookmarks and the other project-related bookmarks in Bookmark+ and (b) the project-related aids in Icicles.

  2. You can create abbreviations for long directory names -- see directory-abbrev-alist.

I'll also mention filecache.el. It basically provides a specialized completion (which you can bind to a key for use when entering file names) which first completes on "filenames, regardless of directory", and once that is complete, cycles through the few directories where such files are found.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top