问题
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).
回答1:
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")]
) ))
回答2:
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
回答3:
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.
You can create abbreviations for long directory names -- see
directory-abbrev-alist
.
回答4:
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.
来源:https://stackoverflow.com/questions/19283368/how-can-i-open-quickly-a-file-in-emacs