问题
Z is a popular shell tool for jumping around commonly used directories. It uses "frecency" as a metric for determining which directory you intend to jump to based on keyword completions. So if I commonly cd to ~/.ssh
, I can z ssh
to jump there.
My question is how can I get the same functionality to work inside Emacs? That is, I want to be able to use ido-find-file
or something similar but only have to type a few characters to jump to the directory I intended. Hopefully the solution can incorporate z
itself so it makes use of the frecency metric already recorded by z
.
回答1:
I used z once but then I found fasd, which is inspired by autojump, z or v, and which I found much more powerful, if I remember well it is because:
- it not only finds directories but also files
- it can
cd
a result or usemplayer
or your editor or another command - the completion is better, specially for zsh (again, if I remember well). The thing is, I constantly use the
d
alias to change directories.
Anyway, there's an emacs package to find files with it: https://github.com/steckerhalter/emacs-fasd That's cool, but it isn't as interactive as I would like.
edit: then I had to update the package and:
(setq fasd-enable-initial-prompt nil) ;; don't ask for first query but fire fuzzy completion straight away.
There's a still a use case that isn't filled:
How to use fasd (or autojump or z) with completion in an emacs shell ?
I often use emacs' shell-mode. When I use my favorite alias d
, it works, but I don't have completion at all. Here, zsh's completion is clearly missing. So I would like to use ido completion, for instance. I wrote a little function which you can easily adapt for z:
edit: finished the command and added ido completion triggered by TAB. Now type d
(d followed by a space). If it keeps changing and if I manage to create a minor mode I'll post the link to my gitlab repo.
edit: I created a mode for this feature: https://gitlab.com/emacs-stuff/fasd-shell/tree/master
;; Use the fasd command line utility to change recently visited directories and more.
(defun fasd-get-path-list (pattern)
"call fasd with pattern and return the list of possibilities"
(s-split "\n" (s-trim (shell-command-to-string (format "fasd -l -R %s" pattern))))
)
(defun fasd ()
"If current shell command is `d something' call fasd"
(interactive)
(let* ((user-input (buffer-substring-no-properties (comint-line-beginning-position)
(point-max))))
(if (and (string= (substring user-input 0 2) "d ")) ;; todo: mapping to use something else than d and change directory.
(progn
;; get what is after "d "
(setq fasd-pattern (buffer-substring-no-properties (+ (comint-line-beginning-position) 2) (point-max)))
(setq fasd-command (concat "cd " (ido-completing-read "cd to: " (fasd-get-path-list fasd-pattern))))
(comint-kill-input)
(insert fasd-command)
(comint-send-input)
))))
;; Use TAB as in normal shell. Now we have even better completion than in zsh !
(define-key shell-mode-map (kbd "<tab>") 'fasd) ;; works like a charm :)
As a side note, I don't use it very often because I open shells in the directory of the current buffer with shell-here and shell-pop (a drop-down terminal like guake for gnome).
回答2:
Within a project, I find projectile
(Projectile) mode to be really helpful.
I use the standard keybindings C-p f
or M-x projectile-find-file
.
It does fuzzy matching on filenames and filters on recently used files.
来源:https://stackoverflow.com/questions/25277748/use-z-jump-around-in-emacs-to-find-directories