tags:

views:

78

answers:

2

In Emacs find-file, if I give it a file like

/a/b//c/d

It complains that it's can't find file /c/d

How can I get emacs to behave more like csh? Ie //+ should be treated the same as / instead of as a marker to start a fresh/new path.

+4  A: 

For Emacs 23.1, this solution works (with default Emacs settings):

(defadvice minibuffer-complete-and-exit (before minibuffer-complete-and-exit activate)
  "translate all occurrences of multiple / into single /"
  (let ((unread-command-events t))
(save-excursion (replace-regexp "/+" "/" nil (point-min) (point-max)))
(message nil)))

I don't have access to Emacs 22.*, so you'll have to try both, but I suspect the solution below works.

For Emacs 21.3, the earlier answer works:

This seems to do the trick (hit TAB to see it in action):

(defadvice read-file-name-internal (before read-file-name-internal-reduce-slash activate)
  "translate all occurrences of multiple / into single /"
  (ad-set-arg 0 (replace-regexp-in-string "/+" "/" (ad-get-arg 0))))

This does require you to type TAB to get the translation to happen.

edited to add:

To get the effect without hitting TAB, use this code:

(define-key minibuffer-local-map (kbd "RET") 'exit-minibuffer-reduce-slash-if-in-find-file)
(defun exit-minibuffer-reduce-slash-if-in-find-file ()
  "when finding a file translate all occurrences of multiple / into single /"
  (interactive)
  (when (or nil minibuffer-completing-file-name)
    (goto-char (point-min))
    (while (re-search-forward "//+" nil t)
      (replace-match "/")))
  (call-interactively 'exit-minibuffer))
Trey Jackson
great tip. The double-slash-means-filesystem-root happens to me rarely but when it strikes, it is jarring. This is handy.
Cheeso
A: 

Emacs uses substitute-in-file-name to do several substitution in file names. One is (from function doc string):

If //' appears, everything up to and including the first of those/' is discarded.

Sadly this function is not customizable. But you can create an advice to remove multiple slashes before actual execution of substitute-in-file-name:

(defadvice substitute-in-file-name (before fixup-double-slashes activate)
  (ad-set-arg 0 (replace-regexp-in-string "//+" "/" (ad-get-arg 0))))
Jürgen Hötzel